精华内容
下载资源
问答
  • 原文地址:Pythonic Data Cleaning With NumPy and Pandas原文作者:Malay Agarwal译文出自:掘金翻译计划本文永久链接:github....Python数据清理数据科学家花费大量时间清理数据集,将它们清理为可以...
    原文地址: Pythonic Data Cleaning With NumPy and Pandas原文作者: Malay Agarwal译文出自: 掘金翻译计划本文永久链接: github.com/xitu/gold-m…译者: bambooom校对者: luochen1992Hopsken


    使用 NumPy 和 Pandas 进行 Python 式数据清理



    数据科学家花费大量时间清理数据集,将它们清理为可以工作的形式。事实上,很多数据科学家表示,80% 的工作都是获取和清理数据。

    因此,不管你是刚刚进入这个领域或者计划进入,那么处理混乱数据的能力会非常重要,无论这意味着缺失值、格式不一致、格式错误还是无意义的异常值。

    在此教程中,我们将利用 Pandas 和 NumPy 这两个库来清理数据。

    我们将介绍以下内容:

    • 删除 DataFrame 中不必要的列
    • 更改 DataFrame 的索引
    • .str() 方法清理列
    • 使用 DataFrame.applymap() 函数以元素方式清理数据集
    • 将列重命名为更易识别的标签
    • 跳过 CSV 文件中不必要的行

    这些是我们将要用到的数据集:

    你可以从 Real Python 的 GitHub 仓库 下载所有数据集,以便查看以下示例。

    注意:我推荐使用 Jupyter Notebook 来进行以下步骤。

    本教程假设你对 Pandas 和 NumPy 库有基本的了解,包括 Pandas 的主要工作对象 SeriesDataFrame,应用于它们的常用方法,以及熟悉 NumPy 的 NaN 值。

    让我们从 import 这些模块开始吧!

    >>> import pandas as pd
    >>> import numpy as np
    

    删除 DataFrame 中不必要的列

    你经常会发现数据集中并非所有类别的数据都对你有用。例如,你可能有一个数据集包含了学生信息(名字、成绩、标准、父母姓名和住址),但你想要专注于分析学生的成绩。

    在这种情况下,住址和父母姓名对你来说并不重要,保留这些类别将占用不必要的空间,并可能拖累运行时间。

    Pandas 提供了一个很方便的 drop() 函数来从 DataFrame 中移除列或行。我们来看一个简单的例子,从 DataFrame 中删除一些列。

    首先,我们从 CSV 文件 “BL-Flickr-Images-Book.csv” 中创建一个 DataFrame。在下面的例子中,我们把相对路径传递给 pd.read_csv,当前工作路径下,所有的数据集都存放在 Datasets 文件夹中:


    >>> df = pd.read_csv('Datasets/BL-Flickr-Images-Book.csv')
    >>> df.head()
    
        Identifier             Edition Statement      Place of Publication  \
    0         206                           NaN                    London
    1         216                           NaN  London; Virtue & Yorston
    2         218                           NaN                    London
    3         472                           NaN                    London
    4         480  A new edition, revised, etc.                    London
    
      Date of Publication              Publisher  \
    0         1879 [1878]       S. Tinsley & Co.
    1                1868           Virtue & Co.
    2                1869  Bradbury, Evans & Co.
    3                1851          James Darling
    4                1857   Wertheim & Macintosh
    
                                                   Title     Author  \
    0                  Walter Forbes. [A novel.] By A. A      A. A.
    1  All for Greed. [A novel. The dedication signed...  A., A. A.
    2  Love the Avenger. By the author of “All for Gr...  A., A. A.
    3  Welsh Sketches, chiefly ecclesiastical, to the...  A., E. S.
    4  [The World in which I live, and my place in it...  A., E. S.
    
                                       Contributors  Corporate Author  \
    0                               FORBES, Walter.               NaN
    1  BLAZE DE BURY, Marie Pauline Rose - Baroness               NaN
    2  BLAZE DE BURY, Marie Pauline Rose - Baroness               NaN
    3                   Appleyard, Ernest Silvanus.               NaN
    4                           BROOME, John Henry.               NaN
    
       Corporate Contributors Former owner  Engraver Issuance type  \
    0                     NaN          NaN       NaN   monographic
    1                     NaN          NaN       NaN   monographic
    2                     NaN          NaN       NaN   monographic
    3                     NaN          NaN       NaN   monographic
    4                     NaN          NaN       NaN   monographic
    
                                              Flickr URL  \
    0  http://www.flickr.com/photos/britishlibrary/ta...
    1  http://www.flickr.com/photos/britishlibrary/ta...
    2  http://www.flickr.com/photos/britishlibrary/ta...
    3  http://www.flickr.com/photos/britishlibrary/ta...
    4  http://www.flickr.com/photos/britishlibrary/ta...
    
                                Shelfmarks
    0    British Library HMNTS 12641.b.30.
    1    British Library HMNTS 12626.cc.2.
    2    British Library HMNTS 12625.dd.1.
    3    British Library HMNTS 10369.bbb.15.
    4    British Library HMNTS 9007.d.28.
    

    当我们使用 head() 方法查看前五条数据时,我们可以看到一些列提供了对图书馆来说有用的辅助信息,但是对描述书籍本身并没有太多帮助: Edition StatementCorporate AuthorCorporate ContributorsFormer ownerEngraverIssuance typeShelfmarks

    我们可以这样删除这些列:

    >>> to_drop = ['Edition Statement',
    ...            'Corporate Author',
    ...            'Corporate Contributors',
    ...            'Former owner',
    ...            'Engraver',
    ...            'Contributors',
    ...            'Issuance type',
    ...            'Shelfmarks']
    
    >>> df.drop(to_drop, inplace=True, axis=1)
    

    这里,我们定义了一个列表,其中包含了我们想要删除的列的名字。然后调用 drop() 函数,传入 inplace 参数为 True,以及 axis 参数为 1。这两个参数告诉 Pandas 我们想要让改变直接作用在对象上,并且我们需要删除的是列。

    再次查看 DataFrame,可以发现不想要的列已经被移除了:

    >>> df.head()
       Identifier      Place of Publication Date of Publication  \
    0         206                    London         1879 [1878]
    1         216  London; Virtue & Yorston                1868
    2         218                    London                1869
    3         472                    London                1851
    4         480                    London                1857
    
                   Publisher                                              Title  \
    0       S. Tinsley & Co.                  Walter Forbes. [A novel.] By A. A
    1           Virtue & Co.  All for Greed. [A novel. The dedication signed...
    2  Bradbury, Evans & Co.  Love the Avenger. By the author of “All for Gr...
    3          James Darling  Welsh Sketches, chiefly ecclesiastical, to the...
    4   Wertheim & Macintosh  [The World in which I live, and my place in it...
    
          Author                                         Flickr URL
    0      A. A.  http://www.flickr.com/photos/britishlibrary/ta...
    1  A., A. A.  http://www.flickr.com/photos/britishlibrary/ta...
    2  A., A. A.  http://www.flickr.com/photos/britishlibrary/ta...
    3  A., E. S.  http://www.flickr.com/photos/britishlibrary/ta...
    4  A., E. S.  http://www.flickr.com/photos/britishlibrary/ta...
    
    或者,我们可以通过直接将列传递给  columns  参数来删除列,不用单独指定删除的标签以及删除列还是行:
    >>> df.drop(columns=to_drop, inplace=True)
    

    这种方法更直观易读,这一步做了什么是非常明显的。

    如果你事先知道那些列是你需要保留的,另外一个选择是将列作为 usecols 的参数传给 pd.read_csv

    更改 DataFrame 的索引

    Pandas 的 Index 扩展了 NumPy 的数组功能,从而可以实现更多功能的截取和标签。在多数情况下,使用数据唯一有价值的标识字段作为索引是很有帮助的。

    例如,在上一节使用的数据集中,可以想象到,图书管理员如果需要搜索记录,他也许输入的是书籍的唯一标识符(Identifier 列):

    >>> df['Identifier'].is_unique
    True
    
    让我们用  set_index  来替换现有的索引:
    >>> df = df.set_index('Identifier')
    >>> df.head()
                    Place of Publication Date of Publication  \
    206                           London         1879 [1878]
    216         London; Virtue & Yorston                1868
    218                           London                1869
    472                           London                1851
    480                           London                1857
    
                            Publisher  \
    206              S. Tinsley & Co.
    216                  Virtue & Co.
    218         Bradbury, Evans & Co.
    472                 James Darling
    480          Wertheim & Macintosh

    技术细节: 与 SQL 中的主键不同,Pandas 的 Index 不保证是唯一的,尽管许多索引及合并操作在唯一的情况下运行时会加速。

    我们可以使用 loc[] 直接访问每条记录。尽管 loc[] 可能不具有直观的名称,但它允许我们执行基于标签的索引,即标记某一行或某一条记录而不用考虑其位置:

    >>> df.loc[206]
    Place of Publication                                               London
    Date of Publication                                           1879 [1878]
    Publisher                                                S. Tinsley & Co.
    Title                                   Walter Forbes. [A novel.] By A. A
    Author                                                              A. A.
    Flickr URL              http://www.flickr.com/photos/britishlibrary/ta...
    Name: 206, dtype: object
    

    换句话说,206 是索引的第一个标签。如要按位置访问它,我们可以使用 df.iloc[0],它执行基于位置的索引。

    技术细节.loc[] 在技术上来说是一个类实例,它有一些特殊的语法不完全符合大多数普通 Python 实例方法。

    一开始,我们的索引是一个 RangeIndex,也就是从 0 开始的整数,类似于 Python 内置的 range。通过把列的名称传给 set_index,我们将索引改成了 Identifier 中的值。

    你可能注意到,我们使用 df = df.set_index(...) 将此方法返回的值重新赋值给变量。这是因为默认情况下,此方法会返回一个修改后的副本,并不会直接对原本的对象进行更改,索引可以通过设置 inplace 参数来避免这种情况:

    df.set_index('Identifier', inplace=True)
    

    整理数据中的字段

    到这里,我们已经删除了不必要的列,并将 DataFrame 的索引更改为更有意义的列。在这一节,我们将会清理特定的列,使其成为统一的格式,以便更好地理解数据集并强化一致性。具体来说,我们将清理 Date of PublicationPlace of Publication 这两列。

    经过检查,所有的数据类型都是 object dtype,它与 Python 中的 str 类似。

    它封装了任何不适用于数字或分类数据的字段。这是有道理的,因为我们使用的数据最初只是一堆杂乱的字符:

    >>> df.get_dtype_counts()
    object    6
    
    其中出版日期一列,如果将其转化为数字类型更有意义,所以我们可以进行如下计算:
    >>> df.loc[1905:, 'Date of Publication'].head(10)
    Identifier
    1905           1888
    1929    1839, 38-54
    2836        [1897?]
    2854           1865
    2956        1860-63
    2957           1873
    3017           1866
    3131           1899
    4598           1814
    4884           1820
    Name: Date of Publication, dtype: object
    

    一本书只能有一个出版日期,因此我们需要做到以下几点:

    • 除去方括号内的多余日期,不管出现在哪里,例如:1879 [1878]
    • 将日期范围转换为“开始日期”,例如:1860-63; 1839, 38-54
    • 完全移除任何不确定的日期,并用 NumPy 的 NaN 值替代:[1897?]
    • 将字符串 nan 也转换为 NumPy 的 NaN

    综合以上,我们实际上可以利用一个正则表达式来提取出版年份:

    regex = r'^(\d{4})'
    

    这个正则表达式意图在字符串的开头找到四位数字,这足以满足我们的要求。上面是一个原始字符串(这意味着反斜杠不再是转义字符),这是正则表达式的标准做法。

    \d 表示任何数字,{4} 表示重复 4 次,^ 表示匹配字符串的开头,括号表示一个捕获组,它向 Pandas 表明我们想要提取正则表达式的这部分。(我们希望用 ^ 来避免字符串从 [ 开始的情况。)

    现在让我们来看看我们在数据集中运行这个表达式时会发生什么:

    >>> extr = df['Date of Publication'].str.extract(r'^(\d{4})', expand=False)
    >>> extr.head()
    Identifier
    206    1879
    216    1868
    218    1869
    472    1851
    480    1857
    Name: Date of Publication, dtype: object
    

    对正则不熟悉?你可以在 regex101.com 这个网站上查看上面这个正则表达式,也可以阅读更多 Python 正则表达式 HOWTO 上的教程。

    从技术上讲,这一列仍然是 object dtype,但是我们用 pd.to_numeric 即可轻松获取数字:

    >>> df['Date of Publication'] = pd.to_numeric(extr)
    >>> df['Date of Publication'].dtype
    dtype('float64')
    
    这么做会导致十分之一的值丢失,但这相对于能够对剩余的有效值上进行计算而已,是一个比较小的代价:
    >>> df['Date of Publication'].isnull().sum() / len(df)
    0.11717147339205986
    
    很好!本节完成了!

    结合 NumPy 以及 str 方法来清理列

    上一部分,你可能已经注意到我们使用了 df['Date of Publication'].str。这个属性是访问 Pandas 的快速字符串操作的一种方式,它主要模仿了原生 Python 中的字符串或编译的正则表达式方法,例如 .split().replace().capitalize()

    为了清理 Place of Publication 字段,我们可以结合 Pandas 的 str 方法以及 NumPy 的 np.where 函数,这个函数基本上是 Excel 里的 IF() 宏的矢量化形式。它的语法如下:

    >>> np.where(condition, then, else)
    

    这里,condition 可以是一个类似数组的对象或者一个布尔遮罩,如果 conditionTrue,则使用 then 值,否则使用 else 值。

    从本质上来说,.where() 函数对对象中的每个元素进行检查,看 condition 是否为 True,并返回一个 ndarray 对象,包含then 或者 else 的值。

    它也可以被用于嵌套的 if-then 语句中,允许我们根据多个条件进行计算:

    >>> np.where(condition1, x1, 
            np.where(condition2, x2, 
                np.where(condition3, x3, ...)))
    
    我们将用这两个函数来清理  Place of Publication  一列,因为此列包含字符串。以下是该列的内容:
    >>> df['Place of Publication'].head(10)
    Identifier
    206                                  London
    216                London; Virtue & Yorston
    218                                  London
    472                                  London
    480                                  London
    481                                  London
    519                                  London
    667     pp. 40. G. Bryan & Co: Oxford, 1898
    874                                 London]
    1143                                 London
    Name: Place of Publication, dtype: object
    

    我们发现某些行中,出版地被其他不必要的信息包围着。如果观察更多值,我们会发现只有出版地包含 ‘London’ 或者 ‘Oxford’ 的行才会出现这种情况。

    我们来看看两条特定的数据:

    >>> df.loc[4157862]
    Place of Publication                                  Newcastle-upon-Tyne
    Date of Publication                                                  1867
    Publisher                                                      T. Fordyce
    Title                   Local Records; or, Historical Register of rema...
    Author                                                        T.  Fordyce
    Flickr URL              http://www.flickr.com/photos/britishlibrary/ta...
    Name: 4157862, dtype: object
    
    >>> df.loc[4159587]
    Place of Publication                                  Newcastle upon Tyne
    Date of Publication                                                  1834
    Publisher                                                Mackenzie & Dent
    Title                   An historical, topographical and descriptive v...
    Author                                               E. (Eneas) Mackenzie
    Flickr URL              http://www.flickr.com/photos/britishlibrary/ta...
    Name: 4159587, dtype: object
    

    这两本书在用一个地方出版,但是一个地名中间包含连字符,另一个没有。

    想要一次性清理这一列,我们可以用 str.contains() 来获得一个布尔掩码。

    我们按如下方式清理此列:

    >>> pub = df['Place of Publication']
    >>> london = pub.str.contains('London')
    >>> london[:5]
    Identifier
    206    True
    216    True
    218    True
    472    True
    480    True
    Name: Place of Publication, dtype: bool
    
    >>> oxford = pub.str.contains('Oxford')
    
    与  np.where  结合:
    df['Place of Publication'] = np.where(london, 'London',
                                          np.where(oxford, 'Oxford',
                                                   pub.str.replace('-', ' ')))
    
    >>> df['Place of Publication'].head()
    Identifier
    206    London
    216    London
    218    London
    472    London
    480    London
    Name: Place of Publication, dtype: object
    

    这里,np.where 函数在嵌套结果中被调用,condition 是从 str.contains() 返回的布尔值的 Series 对象。contains() 方法类似原生 Python 中内置的 in 关键字,它被用来查找一个迭代器中某个实体是否出现(或者字符串中是否有某子字符串)。

    替换的是我们想要的出版地点的字符串。我们也用 str.replace() 方法将连字符替换成了空格然后重新赋值给 DataFrame 的列。

    虽然这个数据集中还有很多脏数据,我们现在只讨论这两列。

    让我们来重新看看前五项,看起来比最开始的时候清晰多了:

    >>> df.head()
               Place of Publication Date of Publication              Publisher  \
    206                      London                1879        S. Tinsley & Co.
    216                      London                1868           Virtue & Co.
    218                      London                1869  Bradbury, Evans & Co.
    472                      London                1851          James Darling
    480                      London                1857   Wertheim & Macintosh
    
                                                            Title    Author  \
    206                         Walter Forbes. [A novel.] By A. A        AA
    216         All for Greed. [A novel. The dedication signed...   A. A A.
    218         Love the Avenger. By the author of “All for Gr...   A. A A.
    472         Welsh Sketches, chiefly ecclesiastical, to the...   E. S A.
    480         [The World in which I live, and my place in it...   E. S A.
    
                                                       Flickr URL
    206         http://www.flickr.com/photos/britishlibrary/ta...
    216         http://www.flickr.com/photos/britishlibrary/ta...
    218         http://www.flickr.com/photos/britishlibrary/ta...
    472         http://www.flickr.com/photos/britishlibrary/ta...
    480         http://www.flickr.com/photos/britishlibrary/ta...
    

    注意:到这里,Place of Publication 会是一个很好转化为 Categorical dtype 的列,因为我们可以用整数对比较小的唯一的城市进行编码。(分类数据类型的内存使用量与类别数目加上数据长度成正比,dtype 对象的大小是一个常数乘以数据长度。

    使用 applymap 函数清理整个数据集

    在某些情况下,你会发现不仅是某一列里有脏数据,而是分散在整个数据集。

    有时如果可以对 DataFrame 里的每个单元或元素都应用一个自定义函数会很有帮助。Pandas 的 .applymap() 函数类似内置的 map() 函数,只是它将应用于 DataFrame 中的所有元素。

    让我们来看个例子,我们将从 “university_towns.txt” 文件中创建 DataFrame

    $ head Datasets/univerisity_towns.txt
    Alabama[edit]
    Auburn (Auburn University)[1]
    Florence (University of North Alabama)
    Jacksonville (Jacksonville State University)[2]
    Livingston (University of West Alabama)[2]
    Montevallo (University of Montevallo)[2]
    Troy (Troy University)[2]
    Tuscaloosa (University of Alabama, Stillman College, Shelton State)[3][4]
    Tuskegee (Tuskegee University)[5]
    Alaska[edit]

    我们发现州名后面跟着大学城的名字这样周期性出现:StateA TownA1 TownA2 StateB TownB1 TownB2…,如果我们在文件中查看州名的写法,会发现所有都有一个 “[edit]” 子字符串。

    我们可以利用这个模式创建一个 (state, city) 元组列表,并将它放入 DataFrame

    >>> university_towns = []
    >>> with open('Datasets/university_towns.txt') as file:
    ...     for line in file:
    ...         if '[edit]' in line:
    ...             # Remember this `state` until the next is found
    ...             state = line
    ...         else:
    ...             # Otherwise, we have a city; keep `state` as last-seen
    ...             university_towns.append((state, line))
    
    >>> university_towns[:5]
    [('Alabama[edit]\n', 'Auburn (Auburn University)[1]\n'),
     ('Alabama[edit]\n', 'Florence (University of North Alabama)\n'),
     ('Alabama[edit]\n', 'Jacksonville (Jacksonville State University)[2]\n'),
     ('Alabama[edit]\n', 'Livingston (University of West Alabama)[2]\n'),
     ('Alabama[edit]\n', 'Montevallo (University of Montevallo)[2]\n')]
    

    我们可以将这个列表包入 DataFrame 中,并将列起名为 “State” 和 “RegionName”。Pandas 会获取每个列表中的元素,将左边的值放入 State 列,右边的值放入 RegionName 列。

    生成的 DataFrame 如下:

    >>> towns_df = pd.DataFrame(university_towns,
    ...                         columns=['State', 'RegionName'])
    
    >>> towns_df.head()
     State                                         RegionName
    0  Alabama[edit]\n                    Auburn (Auburn University)[1]\n
    1  Alabama[edit]\n           Florence (University of North Alabama)\n
    2  Alabama[edit]\n  Jacksonville (Jacksonville State University)[2]\n
    3  Alabama[edit]\n       Livingston (University of West Alabama)[2]\n
    4  Alabama[edit]\n         Montevallo (University of Montevallo)[2]\n
    

    尽管我们可以使用 for 循环来清理上面的字符串,但是使用 Pandas 会更加方便。我们只需要州名和城镇名字,其他都可以删除。虽然这里也可以再次使用 .str() 方法,但我们也可以使用 applymap() 方法将一个 Python 可调用方法映射到 DataFrame 的每个元素上。

    我们一直在使用元素这个术语,但实际上到底是指什么呢?看一下以下这个 DataFrame 例子:

            0           1
    0    Mock     Dataset
    1  Python     Pandas
    2    Real     Python
    3   NumPy     Clean
    
    在这个例子中,每个单元格(‘Mock’、‘Dataset’、‘Python’、‘Pandas’ 等)都是一个元素。所以  applumap()  方法将函数作用于每个元素上。假设定义函数为:
    >>> def get_citystate(item):
    ...     if ' (' in item:
    ...         return item[:item.find(' (')]
    ...     elif '[' in item:
    ...         return item[:item.find('[')]
    ...     else:
    ...         return item
    
    Pandas 的  .applymap()  只接受一个参数,也就是将会作用于每个元素上的函数(可调用):
    >>> towns_df =  towns_df.applymap(get_citystate)
    

    首先,我们定义一个 Python 函数,它以 DataFrame 中的元素作为参数。在函数内部,执行元素是否包含 ([ 的检查。

    函数返回的值取决于这个检查。最后,applymap() 函数在我们的 DataFrame 对象上被调用。现在我们的 DataFrame 对象更加简洁了。

    >>> towns_df.head()
         State    RegionName
    0  Alabama        Auburn
    1  Alabama      Florence
    2  Alabama  Jacksonville
    3  Alabama    Livingston
    4  Alabama    Montevallo
    

    applymap() 方法从 DataFrame 中获取每个元素,将它传递给函数,然后将原来的值替换为函数返回的值。就是这么简单!

    技术细节:虽然它是一个方便多功能的方法,但 .applymap() 对于较大的数据集会有明显的运行时间,因为它将可调用的 Python 函数映射到每个单独元素。某些情况下,使用 Cython 或者 NumPy (调用 C 语言)里的矢量化操作更高效。

    列的重命名以及跳过行

    通常,需要处理的数据集可能包含不易理解的列名,或者某些包含不重要信息的行,它们可能是最前面的有关术语定义的几行,或者最末尾的脚注。

    在这种情况下,我们希望重命名列以及跳过某些行,以便我们可以只对必要的信息以及有意义的标签进行深入分析。

    为了说明我们如何做到这一点,我们先来看一看 “olympics.csv” 数据集的前五行:

    $ head -n 5 Datasets/olympics.csv
    0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
    ,? Summer,01 !,02 !,03 !,Total,? Winter,01 !,02 !,03 !,Total,? Games,01 !,02 !,03 !,Combined total
    Afghanistan (AFG),13,0,0,2,2,0,0,0,0,0,13,0,0,2,2
    Algeria (ALG),12,5,2,8,15,3,0,0,0,0,15,5,2,8,15
    Argentina (ARG),23,18,24,28,70,18,0,0,0,0,41,18,24,28,70
    
    然后,将它读入 Pandas 的 DataFrame 中:
    >>> olympics_df = pd.read_csv('Datasets/olympics.csv')
    >>> olympics_df.head()
                       0         1     2     3     4      5         6     7     8  \
    0                NaN  ? Summer  01 !  02 !  03 !  Total  ? Winter  01 !  02 !
    1  Afghanistan (AFG)        13     0     0     2      2         0     0     0
    2      Algeria (ALG)        12     5     2     8     15         3     0     0
    3    Argentina (ARG)        23    18    24    28     70        18     0     0
    4      Armenia (ARM)         5     1     2     9     12         6     0     0
    
          9     10       11    12    13    14              15
    0  03 !  Total  ? Games  01 !  02 !  03 !  Combined total
    1     0      0       13     0     0     2               2
    2     0      0       15     5     2     8              15
    3     0      0       41    18    24    28              70
    4     0      0       11     1     2     9              12
    

    这确实很凌乱!列是从 0 开始索引的字符串形式的数字。应该是头部的行(也就是应该设置为列名的行)位于 olympics_df.iloc[0]。发生这种情况是因为我们的 csv 文件是以 0、1、2…15 开头的。

    另外,如果我们去查看数据集的来源,会发现 NaN 应该是类似 “Country”,?Summer 应该代表的是 “Summer Games”,而 01! 应该是 “Gold” 等等。

    所以,我们需要做以下两件事:

    • 跳过一行,将第一行(索引为 0)设置为 header
    • 重命名这些列

    我们可以在读取 CSV 文件时通过传递一些参数给 read_csv() 函数来跳过某行并设置 header。

    这个函数有很多可选的参数,但这个情况里,我们只需要一个参数(header)来移除第 0 行:

    >>> olympics_df = pd.read_csv('Datasets/olympics.csv', header=1)
    >>> olympics_df.head()
              Unnamed: 0  ? Summer  01 !  02 !  03 !  Total  ? Winter  \
    0        Afghanistan (AFG)        13     0     0     2      2         0
    1            Algeria (ALG)        12     5     2     8     15         3
    2          Argentina (ARG)        23    18    24    28     70        18
    3            Armenia (ARM)         5     1     2     9     12         6
    4  Australasia (ANZ) [ANZ]         2     3     4     5     12         0
    
       01 !.1  02 !.1  03 !.1  Total.1  ? Games  01 !.2  02 !.2  03 !.2  \
    0       0       0       0        0       13       0       0       2
    1       0       0       0        0       15       5       2       8
    2       0       0       0        0       41      18      24      28
    3       0       0       0        0       11       1       2       9
    4       0       0       0        0        2       3       4       5
    
       Combined total
    0               2
    1              15
    2              70
    3              12
    4              12
    

    我们现在已经有了正确的 header 行,以及移除了所有不必要的行。注意 Pandas 将包含国家名字的列的名字从 NaN 变成了 Unnames:0

    要重命名列,我们将利用 rename() 方法,这个方法允许你基于一个映射(本例中,指字典)来重新标记轴的名字。

    让我们从定义一个新的字典开始,它将现在的列的名字作为 key,映射到可用性更强的名字(字典值)。

    >>> new_names =  {'Unnamed: 0': 'Country',
    ...               '? Summer': 'Summer Olympics',
    ...               '01 !': 'Gold',
    ...               '02 !': 'Silver',
    ...               '03 !': 'Bronze',
    ...               '? Winter': 'Winter Olympics',
    ...               '01 !.1': 'Gold.1',
    ...               '02 !.1': 'Silver.1',
    ...               '03 !.1': 'Bronze.1',
    ...               '? Games': '# Games',
    ...               '01 !.2': 'Gold.2',
    ...               '02 !.2': 'Silver.2',
    ...               '03 !.2': 'Bronze.2'}
    
    然后调用  rename()  函数:
    >>> olympics_df.rename(columns=new_names, inplace=True)
    
    将  inplace  参数设置为  True  可以将变化直接作用于我们的  DataFrame  对象上。让我们看看是否生效:
    >>> olympics_df.head()
                       Country  Summer Olympics  Gold  Silver  Bronze  Total  \
    0        Afghanistan (AFG)               13     0       0       2      2
    1            Algeria (ALG)               12     5       2       8     15
    2          Argentina (ARG)               23    18      24      28     70
    3            Armenia (ARM)                5     1       2       9     12
    4  Australasia (ANZ) [ANZ]                2     3       4       5     12
    
       Winter Olympics  Gold.1  Silver.1  Bronze.1  Total.1  # Games  Gold.2  \
    0                0       0         0         0        0       13       0
    1                3       0         0         0        0       15       5
    2               18       0         0         0        0       41      18
    3                6       0         0         0        0       11       1
    4                0       0         0         0        0        2       3
    
       Silver.2  Bronze.2  Combined total
    0         0         2               2
    1         2         8              15
    2        24        28              70
    3         2         9              12
    4         4         5              12
    

    Python 数据清理:回顾以及其他资源

    在本教程中,你学习了如何使用 drop() 函数删除不必要的信息,以及如何给你的数据集设置索引以便更加方便的引用其他的项。

    此外,你也学习了如何使用 .str() 清理对象字段,以及如何使用 applymap() 函数清理整个数据集。最后,我们探索了一下如何跳过 CSV 文件中某些列以及使用 rename() 方法重命名列。

    了解数据清理非常重要,因为这是数据科学很重要的一部分。你现在已经对如何使用 Pandas 以及 NumPy 清理数据集有了基本的了解。

    查看以下链接可以帮你找到更多的资源继续你的 Python 数据科学之旅:

    展开全文
  • NumPy is a commonly used Python data analysis package. By using NumPy, you can speed up your workflow, and interface with other packages in the Python ecosystem, like scikit-learn, that use NumPy unde...

    NumPy is a commonly used Python data analysis package. By using NumPy, you can speed up your workflow, and interface with other packages in the Python ecosystem, like scikit-learn, that use NumPy under the hood. NumPy was originally developed in the mid 2000s, and arose from an even older package called Numeric. This longevity means that almost every data analysis or machine learning package for Python leverages NumPy in some way.

    NumPy是一个常用的Python数据分析包。 通过使用NumPy,您可以加快工作流程,并与Python生态系统中的其他软件包(例如scikit-learn)进行交互,这些软件包在后台使用了NumPy。 NumPy最初是在2000年代中期开发的,起源于一个名为Numeric的更老的软件包。 这种长寿意味着几乎所有用于Python的数据分析或机器学习包都以某种方式利用了NumPy。

    In this tutorial, we’ll walk through using NumPy to analyze data on wine quality. The data contains information on various attributes of wines, such as pH and fixed acidity, along with a quality score between 0 and 10 for each wine. The quality score is the average of at least 3 human taste testers. As we learn how to work with NumPy, we’ll try to figure out more about the perceived quality of wine.

    在本教程中,我们将逐步使用NumPy分析葡萄酒质量数据。 数据包含有关葡萄酒各种属性的信息,例如pHfixed acidity ,以及每种葡萄酒的质量得分在010之间。 质量得分是至少3人类味觉测试人员的平均值。 当我们学习如何与NumPy合作时,我们将尝试更多地了解葡萄酒的品质。

    The wines we’ll be analyzing are from the Minho region of Portugal.

    我们将要分析的葡萄酒来自葡萄牙的Minho地区。

    The data was downloaded from the UCI Machine Learning Repository, and is available here. Here are the first few rows of the winequality-red.csv file, which we’ll be using throughout this tutorial:

    数据是从UCI机器学习存储库下载的,可以在这里找到 。 这是winequality-red.csv文件的前几行,我们将在本教程中使用它们:

    "fixed acidity";"volatile acidity";"citric acid";"residual sugar";"chlorides";"free sulfur dioxide";"total sulfur dioxide";"density";"pH";"sulphates";"alcohol";"quality"
    7.4;0.7;0;1.9;0.076;11;34;0.9978;3.51;0.56;9.4;5
    7.8;0.88;0;2.6;0.098;25;67;0.9968;3.2;0.68;9.8;5
    
    "fixed acidity";"volatile acidity";"citric acid";"residual sugar";"chlorides";"free sulfur dioxide";"total sulfur dioxide";"density";"pH";"sulphates";"alcohol";"quality"
    7.4;0.7;0;1.9;0.076;11;34;0.9978;3.51;0.56;9.4;5
    7.8;0.88;0;2.6;0.098;25;67;0.9968;3.2;0.68;9.8;5
    
    

    The data is in what I’m going to call ssv (semicolon separated values) format – each record is separated by a semicolon (;), and rows are separated by a new line. There are 1600 rows in the file, including a header row, and 12 columns.

    数据采用ssv(用分号分隔的值)格式-每条记录用分号( ; )分隔,行用新行分隔。 文件中有1600行,包括标题行和12列。

    Before we get started, a quick version note – we’ll be using Python 3.5. Our code examples will be done using Jupyter notebook.

    在开始之前,请快速阅读一下版本注释–我们将使用Python 3.5 。 我们的代码示例将使用Jupyter notebook完成。

    If you want to jump right into a specific area, here are the topics:

    如果您想直接跳到特定区域,请参考以下主题:

    CSV数据列表列表 (Lists Of Lists for CSV Data)

    Before using NumPy, we’ll first try to work with the data using Python and the csv package. We can read in the file using the csv.reader object, which will allow us to read in and split up all the content from the ssv file.

    在使用NumPy之前,我们将首先尝试使用Python和csv包处理数据。 我们可以使用csv.reader对象读入文件,这将使我们能够读入并拆分ssv文件中的所有内容。

    In the below code, we:

    在下面的代码中,我们:

    • Import the csv library.
    • Open the winequality-red.csv file.
      • With the file open, create a new csv.reader object.
        • Pass in the keyword argument delimiter=";" to make sure that the records are split up on the semicolon character instead of the default comma character.
      • Call the list type to get all the rows from the file.
      • Assign the result to wines.
    • 导入csv库。
    • 打开winequality-red.csv文件。
      • 打开文件后,创建一个新的csv.reader对象。
        • 传递关键字参数delimiter=";" 确保记录以分号而不是默认的逗号分隔。
      • 调用列表类型以获取文件中的所有行。
      • 将结果分配给wines

    In [1]:

    在[1]中:

    Once we’ve read in the data, we can print out the first 3 rows:

    读取数据后,我们可以打印出前3行:

    In [3]:

    在[3]中:

    printprint (( wineswines [:[: 33 ])
    ])
    
    
    [['fixed acidity', 'volatile acidity', 'citric acid', 'residual sugar', 'chlorides', 'free sulfur dioxide', 'total sulfur dioxide', 'density', 'pH', 'sulphates', 'alcohol', 'quality'], ['7.4', '0.7', '0', '1.9', '0.076', '11', '34', '0.9978', '3.51', '0.56', '9.4', '5'], ['7.8', '0.88', '0', '2.6', '0.098', '25', '67', '0.9968', '3.2', '0.68', '9.8', '5']]
    

    The data has been read into a list of lists. Each inner list is a row from the ssv file. As you may have noticed, each item in the entire list of lists is represented as a string, which will make it harder to do computations.

    数据已被读入列表列表。 每个内部列表都是ssv文件中的一行。 您可能已经注意到,整个列表列表中的每个项目都以字符串表示,这将使计算变得更加困难。

    We’ll format the data into a table to make it easier to view:

    我们将数据格式化为表格以使其更易于查看:

    fixed acidity 固定酸度 volatile acidity 挥发性酸度 citric acid 柠檬酸 residual sugar 残留糖 chlorides 氯化物 free sulfur dioxide 游离二氧化硫 total sulfur dioxide 总二氧化硫 density 密度 pH pH值 sulphates 硫酸盐 alcoholquality 质量
    7.4 7.4 0.70 0.70 0 0 1.9 1.9 0.076 0.076 11 11 34 34 0.9978 0.9978 3.51 3.51 0.56 0.56 9.4 9.4 5 5
    7.8 7.8 0.88 0.88 0 0 2.6 2.6 0.098 0.098 25 25 67 67 0.9968 0.9968 3.20 3.20 0.68 0.68 9.8 9.8 5 5

    As you can see from the table above, we’ve read in three rows, the first of which contains column headers. Each row after the header row represents a wine. The first element of each row is the fixed acidity, the second is the volatile acidity, and so on. We can find the average quality of the wines. The below code will:

    从上表中可以看到,我们读了三行,其中第一行包含列标题。 标题行之后的每一行代表一种葡萄酒。 每行的第一个元素是fixed acidity ,第二个元素是volatile acidity ,依此类推。 我们可以找到葡萄酒的平均quality 。 下面的代码将:

    • Extract the last element from each row after the header row.
    • Convert each extracted element to a float.
    • Assign all the extracted elements to the list qualities.
    • Divide the sum of all the elements in qualities by the total number of elements in qualities to the get the mean.
    • 从标题行之后的每一行中提取最后一个元素。
    • 将每个提取的元素转换为浮点数。
    • 将所有提取的元素分配给列表qualities
    • 把所有的元素之和qualities的元素的总数qualities的获得的平均值。

    In [4]:

    在[4]中:

    Out[4]:

    出[4]:

    
    5.6360225140712945
    
    

    Although we were able to do the calculation we wanted, the code is fairly complex, and it won’t be fun to have to do something similar every time we want to compute a quantity. Luckily, we can use NumPy to make it easier to work with our data.

    尽管我们能够进行所需的计算,但是代码却相当复杂,每次我们要计算数量时都必须执行类似的操作并不是一件有趣的事情。 幸运的是,我们可以使用NumPy来简化数据处理。

    Numpy二维数组 (Numpy 2-Dimensional Arrays)

    With NumPy, we work with multidimensional arrays. We’ll dive into all of the possible types of multidimensional arrays later on, but for now, we’ll focus on 2-dimensional arrays. A 2-dimensional array is also known as a matrix, and is something you should be familiar with. In fact, it’s just a different way of thinking about a list of lists. A matrix has rows and columns. By specifying a row number and a column number, we’re able to extract an element from a matrix.

    使用NumPy,我们可以处理多维数组。 稍后,我们将深入探讨所有可能的多维数组类型,但现在,我们将专注于二维数组。 二维数组也称为矩阵,您应该熟悉它。 实际上,这只是考虑列表列表的另一种方式。 矩阵具有行和列。 通过指定行号和列号,我们能够从矩阵中提取元素。

    In the below matrix, the first row is the header row, and the first column is the fixed acidity column:

    在下面的矩阵中,第一行是标题行,第一列是fixed acidity列:

    fixed acidity 固定酸度 volatile acidity 挥发性酸度 citric acid 柠檬酸 residual sugar 残留糖 chlorides 氯化物 free sulfur dioxide 游离二氧化硫 total sulfur dioxide 总二氧化硫 density 密度 pH pH值 sulphates 硫酸盐 alcoholquality 质量
    7.4 7.4 0.70 0.70 0 0 1.9 1.9 0.076 0.076 11 11 34 34 0.9978 0.9978 3.51 3.51 0.56 0.56 9.4 9.4 5 5
    7.8 7.8 0.88 0.88 0 0 2.6 2.6 0.098 0.098 25 25 67 67 0.9968 0.9968 3.20 3.20 0.68 0.68 9.8 9.8 5 5

    If we picked the element at the first row and the second column, we’d get volatile acidity. If we picked the element in the third row and the second column, we’d get 0.88.

    如果我们在第一行和第二列中选择元素,则会得到volatile acidity 。 如果我们在第三行和第二列中选择元素,则将得到0.88

    In a NumPy array, the number of dimensions is called the rank, and each dimension is called an axis. So the rows are the first axis, and the columns are the second axis.

    在NumPy数组中,维数称为等级,每个维数称为轴。 因此,行是第一个轴,列是第二个轴。

    Now that you understand the basics of matrices, let’s see how we can get from our list of lists to a NumPy array.

    现在您已经了解了矩阵的基本知识,让我们看看如何从列表列表中获取NumPy数组。

    创建一个NumPy数组 (Creating A NumPy Array)

    We can create a NumPy array using the numpy.array function. If we pass in a list of lists, it will automatically create a NumPy array with the same number of rows and columns. Because we want all of the elements in the array to be float elements for easy computation, we’ll leave off the header row, which contains strings. One of the limitations of NumPy is that all the elements in an array have to be of the same type, so if we include the header row, all the elements in the array will be read in as strings. Because we want to be able to do computations like find the average quality of the wines, we need the elements to all be floats.

    我们可以使用numpy.array函数创建一个NumPy数组。 如果我们传入一个列表列表,它将自动创建一个具有相同行数和列数的NumPy数组。 因为我们希望数组中的所有元素都是float元素以便于计算,所以我们将省略包含字符串的标题行。 NumPy的局限性之一是数组中的所有元素必须具有相同的类型,因此,如果我们包含标题行,则数组中的所有元素都将作为字符串读取。 因为我们希望能够进行计算,例如找到葡萄酒的平均quality ,所以我们需要所有元素都是浮点数。

    In the below code, we:

    在下面的代码中,我们:

    • Import the numpy package.
    • Pass the list of lists wines into the array function, which converts it into a NumPy array.
      • Exclude the header row with list slicing.
      • Specify the keyword argument dtype to make sure each element is converted to a float. We’ll dive more into what the dtype is later on.
    • 导入numpy包。
    • 将列表wines的列表传递给array函数,该函数将其转换为NumPy数组。
      • 用列表切片排除标题行。
      • 指定关键字参数dtype以确保每个元素都转换为浮点数。 稍后我们将深入探讨dtype

    In [5]:

    在[5]中:

    import import numpy numpy as as np
    
    np
    
    wines wines = = npnp .. arrayarray (( wineswines [[ 11 :], :], dtypedtype == npnp .. floatfloat )
    )
    

    If we display wines, we’ll now get a NumPy array:

    如果展示wines ,我们现在将获得一个NumPy数组:

    Out[6]:

    出[6]:

    
    array([[  7.4  ,   0.7  ,   0.   , ...,   0.56 ,   9.4  ,   5.   ],
           [  7.8  ,   0.88 ,   0.   , ...,   0.68 ,   9.8  ,   5.   ],
           [  7.8  ,   0.76 ,   0.04 , ...,   0.65 ,   9.8  ,   5.   ],
           ..., 
           [  6.3  ,   0.51 ,   0.13 , ...,   0.75 ,  11.   ,   6.   ],
           [  5.9  ,   0.645,   0.12 , ...,   0.71 ,  10.2  ,   5.   ],
           [  6.   ,   0.31 ,   0.47 , ...,   0.66 ,  11.   ,   6.   ]])
    

    We can check the number of rows and columns in our data using the shape property of NumPy arrays:

    我们可以使用NumPy数组的shape属性检查数据中的行数和列数:

    In [7]:

    在[7]中:

    Out[7]:

    出[7]:

    
    (1599, 12)
    
    

    替代的NumPy数组创建方法 (Alternative NumPy Array Creation Methods)

    There are a variety of methods that you can use to create NumPy arrays. To start with, you can create an array where every element is zero. The below code will create an array with 3 rows and 4 columns, where every element is 0, using numpy.zeros:

    您可以使用多种方法来创建NumPy数组。 首先,您可以创建一个数组,其中每个元素均为零。 下面的代码将使用numpy.zeros创建一个具有34列的数组,其中每个元素均为0

    In [8]:

    在[8]中:

    empty_array empty_array = = npnp .. zeroszeros (((( 33 ,, 44 ))
    ))
    empty_array
    empty_array
    

    Out[8]:

    出[8]:

    
    array([[ 0.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  0.]])
    

    It’s useful to create an array with all zero elements in cases when you need an array of fixed size, but don’t have any values for it yet.

    在需要固定大小的数组但尚无任何值的情况下,创建一个全零元素的数组很有用。

    You can also create an array where each element is a random number using numpy.random.rand. Here’s an example:

    您还可以使用numpy.random.rand创建一个数组,其中每个元素都是随机数。 这是一个例子:

    In [9]:

    在[9]中:

    Out[9]:

    出[9]:

    
    array([[ 0.2247223 ,  0.92240549,  0.14541893,  0.61731257],
           [ 0.00154957,  0.82342197,  0.74044906,  0.11466845],
           [ 0.6152478 ,  0.14433138,  0.13009583,  0.22981301]])
    
    

    Creating arrays full of random numbers can be useful when you want to quickly test your code with sample arrays.

    当您想使用示例数组快速测试代码时,创建充满随机数的数组会很有用。

    使用NumPy读取文件 (Using NumPy To Read In Files)

    It’s possible to use NumPy to directly read csv or other files into arrays. We can do this using the numpy.genfromtxt function. We can use it to read in our initial data on red wines.

    可以使用NumPy直接将csv或其他文件读入数组。 我们可以使用numpy.genfromtxt函数执行此操作。 我们可以使用它来读取有关红酒的原始数据。

    In the below code, we:

    在下面的代码中,我们:

    • Use the genfromtxt function to read in the winequality-red.csv file.
    • Specify the keyword argument delimiter=";" so that the fields are parsed properly.
    • Specify the keyword argument skip_header=1 so that the header row is skipped.
    • 使用genfromtxt函数读取winequality-red.csv文件。
    • 指定关键字参数delimiter=";" 以便正确解析字段。
    • 指定关键字参数skip_header=1以便跳过标题行。

    In [62]:

    在[62]中:

    wines wines = = npnp .. genfromtxtgenfromtxt (( "winequality-red.csv""winequality-red.csv" , , delimiterdelimiter == ";"";" , , skip_headerskip_header == 11 )
    )
    

    wines will end up looking the same as if we read it into a list then converted it to an array of floats. NumPy will automatically pick a data type for the elements in an array based on their format.

    wines外观与我们将其读入列表然后将其转换为浮点数组的外观相同。 NumPy将根据其格式自动为数组中的元素选择数据类型。

    索引NumPy数组 (Indexing NumPy Arrays)

    We now know how to create arrays, but unless we can retrieve results from them, there isn’t a lot we can do with NumPy. We can use array indexing to select individual elements, groups of elements, or entire rows and columns. One important thing to keep in mind is that just like Python lists, NumPy is zero-indexed, meaning that the index of the first row is 0, and the index of the first column is 0. If we want to work with the fourth row, we’d use index 3, if we want to work with the second row, we’d use index 1, and so on. We’ll again work with the wines array:

    现在,我们知道如何创建数组,但是除非可以从数组中检索结果,否则NumPy不能做很多事情。 我们可以使用数组索引来选择单个元素,元素组或整个行和列。 要牢记的重要一点是,就像Python列表一样,NumPy的索引为零,这意味着第一行的索引为0 ,第一列的索引为0 。 如果要使用第四行,则使用索引3 ;如果要使用第二行,则使用索引1 ,依此类推。 我们将再次使用wines数组:

    7.4 7.4 0.70 0.70 0.00 0.00 1.9 1.9 0.076 0.076 11 11 34 34 0.9978 0.9978 3.51 3.51 0.56 0.56 9.4 9.4 5 5
    7.8 7.8 0.88 0.88 0.00 0.00 2.6 2.6 0.098 0.098 25 25 67 67 0.9968 0.9968 3.20 3.20 0.68 0.68 9.8 9.8 5 5
    7.8 7.8 0.76 0.76 0.04 0.04 2.3 2.3 0.092 0.092 15 15 54 54 0.9970 0.9970 3.26 3.26 0.65 0.65 9.8 9.8 5 5
    11.2 11.2 0.28 0.28 0.56 0.56 1.9 1.9 0.075 0.075 17 17 60 60 0.9980 0.9980 3.16 3.16 0.58 0.58 9.8 9.8 6 6
    7.4 7.4 0.70 0.70 0.00 0.00 1.9 1.9 0.076 0.076 11 11 34 34 0.9978 0.9978 3.51 3.51 0.56 0.56 9.4 9.4 5 5

    Let’s select the element at row 3 and column 4. In the below code, we pass in the index 2 as the row index, and the index 3 as the column index. This retrieves the value from the fourth column of the third row:

    让我们选择第3行和第4列的元素。 在下面的代码中,我们将索引2作为行索引,将索引3作为列索引。 这将从第三行的第四列中检索值:

    In [11]:

    在[11]中:

    Out[11]:

    出[11]:

    
    2.2999999999999998
    
    

    Since we’re working with a 2-dimensional array in NumPy, we specify 2 indexes to retrieve an element. The first index is the row, or axis 1, index, and the second index is the column, or axis 2, index. Any element in wines can be retrieved using 2 indexes.

    由于我们正在NumPy中使用二维数组,因此我们指定2个索引来检索元素。 第一个索引是行或轴1索引,第二个索引是列或轴2索引。 wines任何元素都可以使用2索引进行检索。

    切片NumPy数组 (Slicing NumPy Arrays)

    If we instead want to select the first three items from the fourth column, we can do it using a colon (:). A colon indicates that we want to select all the elements from the starting index up to but not including the ending index. This is also known as a slice:

    如果我们不是要选择从第四列的前三个项目,我们可以使用一个冒号做( : )。 冒号表示我们要选择从开始索引到结束索引(但不包括结束索引)的所有元素。 这也称为切片:

    In [12]:

    在[12]中:

    wineswines [[ 00 :: 33 ,, 33 ]
    ]
    

    Out[12]:

    出[12]:

    
    array([ 1.9,  2.6,  2.3])
    

    Just like with list slicing, it’s possible to omit the 0 to just retrieve all the elements from the beginning up to element 3:

    就像列表切片一样,可以省略0以仅检索从开始到元素3所有元素:

    In [13]:

    在[13]中:

    Out[13]:

    出[13]:

    
    array([ 1.9,  2.6,  2.3])
    
    

    We can select an entire column by specifying that we want all the elements, from the first to the last. We specify this by just using the colon (:), with no starting or ending indices. The below code will select the entire fourth column:

    我们可以通过指定我们想要从头到尾的所有元素来选择整个列。 (我们只要使用冒号指定此: ),没有开始或结束索引。 下面的代码将选择整个第四列:

    In [14]:

    在[14]中:

    wineswines [:,[:, 33 ]
    ]
    

    Out[14]:

    出[14]:

    
    array([ 1.9,  2.6,  2.3, ...,  2.3,  2. ,  3.6])
    

    We selected an entire column above, but we can also extract an entire row:

    我们在上方选择了整列,但我们也可以提取整行:

    In [15]:

    在[15]中:

    Out[15]:

    出[15]:

    
    array([ 11.2  ,   0.28 ,   0.56 ,   1.9  ,   0.075,  17.   ,  60.   ,
             0.998,   3.16 ,   0.58 ,   9.8  ,   6.   ])
    
    

    If we take our indexing to the extreme, we can select the entire array using two colons to select all the rows and columns in wines. This is a great party trick, but doesn’t have a lot of good applications:

    如果我们将索引扩展到极限,则可以使用两个冒号选择整个数组,以选择wines所有行和列。 这是一个很棒的聚会把戏,但没有很多好的应用程序:

    In [16]:

    在[16]中:

    wineswines [:,:]
    [:,:]
    

    Out[16]:

    出[16]:

    
    array([[  7.4  ,   0.7  ,   0.   , ...,   0.56 ,   9.4  ,   5.   ],
           [  7.8  ,   0.88 ,   0.   , ...,   0.68 ,   9.8  ,   5.   ],
           [  7.8  ,   0.76 ,   0.04 , ...,   0.65 ,   9.8  ,   5.   ],
           ..., 
           [  6.3  ,   0.51 ,   0.13 , ...,   0.75 ,  11.   ,   6.   ],
           [  5.9  ,   0.645,   0.12 , ...,   0.71 ,  10.2  ,   5.   ],
           [  6.   ,   0.31 ,   0.47 , ...,   0.66 ,  11.   ,   6.   ]])
    

    给NumPy数组赋值 (Assigning Values To NumPy Arrays)

    We can also use indexing to assign values to certain elements in arrays. We can do this by assigning directly to the indexed value:

    我们还可以使用索引将值分配给数组中的某些元素。 我们可以通过直接分配索引值来做到这一点:

    In [17]:

    在[17]中:

    We can do the same for slices. To overwrite an entire column, we can do this:

    我们可以对切片执行相同的操作。 要覆盖整个列,我们可以这样做:

    In [18]:

    在[18]中:

    wineswines [:,[:, 1010 ] ] = = 50
    50
    

    The above code overwrites all the values in the eleventh column with 50.

    上面的代码用50覆盖了第11列中的所有值。

    一维NumPy数组 (1-Dimensional NumPy Arrays)

    So far, we’ve worked with 2-dimensional arrays, such as wines. However, NumPy is a package for working with multidimensional arrays. One of the most common types of multidimensional arrays is the 1-dimensional array, or vector. As you may have noticed above, when we sliced wines, we retrieved a 1-dimensional array. A 1-dimensional array only needs a single index to retrieve an element. Each row and column in a 2-dimensional array is a 1-dimensional array. Just like a list of lists is analogous to a 2-dimensional array, a single list is analogous to a 1-dimensional array. If we slice wines and only retrieve the third row, we get a 1-dimensional array:

    到目前为止,我们已经处理了二维数组,例如wines 。 但是,NumPy是用于处理多维数组的软件包。 多维数组的最常见类型之一是一维数组或矢量。 如您在上面可能已经注意到的那样,当我们对wines切片时,我们检索到一维数组。 一维数组仅需要单个索引即可检索元素。 二维数组中的每一行和每一列都是一维数组。 就像列表列表类似于二维数组一样,单个列表类似于一维数组。 如果我们将葡萄酒切成薄片并仅获取第三行,则会得到一维数组:

    In [20]:

    在[20]中:

    Here’s how third_wine looks:

    这是third_wine外观:

    11.200
    0.280
    0.560
    1.900
    0.075
    17.000
    60.000
    0.998
    3.160
    0.580
    9.800
    6.000
    
    11.200
    0.280
    0.560
    1.900
    0.075
    17.000
    60.000
    0.998
    3.160
    0.580
    9.800
    6.000
    
    

    We can retrieve individual elements from third_wine using a single index. The below code will display the second item in third_wine:

    我们可以使用单个索引从third_wine检索单个元素。 下面的代码将在third_wine显示第二个项目:

    In [21]:

    在[21]中:

    Out[21]:

    出[21]:

    
    0.28000000000000003
    
    

    Most NumPy functions that we’ve worked with, such as numpy.random.rand, can be used with multidimensional arrays. Here’s how we’d use numpy.random.rand to generate a random vector:

    我们使用过的大多数NumPy函数,例如numpy.random.rand ,都可以与多维数组一起使用。 这是我们使用numpy.random.rand生成随机向量的方法:

    In [22]:

    在[22]中:

    npnp .. randomrandom .. randrand (( 33 )
    )
    

    Out[22]:

    出[22]:

    
    array([ 0.88588862,  0.85693478,  0.19496774])
    

    Previously, when we called np.random.rand, we passed in a shape for a 2-dimensional array, so the result was a 2-dimensional array. This time, we passed in a shape for a single dimensional array. The shape specifies the number of dimensions, and the size of the array in each dimension. A shape of (10,10) will be a 2-dimensional array with 10 rows and 10 columns. A shape of (10,) will be a 1-dimensional array with 10 elements.

    以前,当我们调用np.random.rand ,我们为二维数组传递了一个形状,因此结果是一个二维数组。 这次,我们为一维数组传递了一个形状。 形状指定维数,以及每个维中数组的大小。 形状(10,10)将是具有1010列的二维数组。 形状(10,)将是包含10元素的一维数组。

    Where NumPy gets more complex is when we start to deal with arrays that have more than 2 dimensions.

    凡NumPy的变得更加复杂是,当我们开始处理有超过阵列2的尺寸。

    N维NumPy数组 (N-Dimensional NumPy Arrays)

    This doesn’t happen extremely often, but there are cases when you’ll want to deal with arrays that have greater than 3 dimensions. One way to think of this is as a list of lists of lists. Let’s say we want to store the monthly earnings of a store, but we want to be able to quickly lookup the results for a quarter, and for a year. The earnings for one year might look like this:

    这种情况并不经常发生,但是在某些情况下,您将需要处理大于3维的数组。 考虑这一点的一种方法是将列表视为列表列表。 假设我们要存储商店的每月收入,但是我们希望能够快速查找季度和一年的结果。 一年的收入可能看起来像这样:

    The store earned $500 in January, $505 in February, and so on. We can split up these earnings by quarter into a list of lists:

    该商店在一月份的收入$500 $505 ,二月份的$505 ,依此类推。 我们可以按季度将这些收入分成以下列表:

    In [23]:

    在[23]中:

    year_one year_one = = [
        [
        [[ 500500 ,, 505505 ,, 490490 ],
        ],
        [[ 810810 ,, 450450 ,, 678678 ],
        ],
        [[ 234234 ,, 897897 ,, 430430 ],
        ],
        [[ 560560 ,, 10231023 ,, 640640 ]
    ]
    ]
    ]
    

    We can retrieve the earnings from January by calling year_one[0][0]. If we want the results for a whole quarter, we can call year_one[0] or year_one[1]. We now have a 2-dimensional array, or matrix. But what if we now want to add the results from another year? We have to add a third dimension:

    我们可以通过调用year_one[0][0]来检索1月的收入。 如果我们需要整个季度的结果,可以调用year_one[0]year_one[1] 。 现在,我们有了一个二维数组或矩阵。 但是,如果我们现在想将另一年的结果相加怎么办? 我们必须添加第三维:

    In [24]:

    在[24]中:

    We can retrieve the earnings from January of the first year by calling earnings[0][0][0]. We now need three indexes to retrieve a single element. A three-dimensional array in NumPy is much the same. In fact, we can convert earnings to an array and then get the earnings for January of the first year:

    我们可以通过调用earnings[0][0][0]来检索第一年1月的earnings[0][0][0] 。 现在,我们需要三个索引来检索单个元素。 NumPy中的三维数组几乎相同。 实际上,我们可以将earnings转换为数组,然后获得第一年一月的收入:

    In [25]:

    在[25]中:

    earnings earnings = = npnp .. arrayarray (( earningsearnings )
    )
    earningsearnings [[ 00 ,, 00 ,, 00 ]
    ]
    

    We can also find the shape of the array:

    我们还可以找到数组的形状:

    In [26]:

    在[26]中:

    Indexing and slicing work the exact same way with a 3-dimensional array, but now we have an extra axis to pass in. If we wanted to get the earnings for January of all years, we could do this:

    索引和切片对3维数组的工作方式完全相同,但是现在我们需要传递一个额外的轴。如果我们想获得所有年份一月的收入,我们可以这样做:

    In [27]:

    在[27]中:

    earningsearnings [:,[:, 00 ,, 00 ]
    ]
    

    Out[27]:

    出[27]:

    
    array([500, 600])
    

    If we wanted to get first quarter earnings from both years, we could do this:

    如果我们想获得两个年度的第一季度收益,我们可以这样做:

    In [28]:

    在[28]中:

    Out[28]:

    出[28]:

    
    array([[500, 505, 490],
           [600, 605, 490]])
    
    

    Adding more dimensions can make it much easier to query your data if it’s organized in a certain way. As we go from 3-dimensional arrays to 4-dimensional and larger arrays, the same properties apply, and they can be indexed and sliced in the same ways.

    如果以某种方式组织数据,则添加更多维度可以使查询数据变得更加容易。 当我们从3维数组变为4维及更大的数组时,将应用相同的属性,并且可以用相同的方式对它们进行索引和切片。

    NumPy数据类型 (NumPy Data Types)

    As we mentioned earlier, each NumPy array can store elements of a single data type. For example, wines contains only float values. NumPy stores values using its own data types, which are distinct from Python types like float and str. This is because the core of NumPy is written in a programming language called C, which stores data differently than the Python data types. NumPy data types map between Python and C, allowing us to use NumPy arrays without any conversion hitches.

    如前所述,每个NumPy数组都可以存储单个数据类型的元素。 例如, wines仅包含浮点值。 NumPy使用自己的数据类型存储值,这与Python类型(例如floatstr 。 这是因为NumPy的核心是用一种称为C的编程语言编写的,该语言存储的数据不同于Python数据类型。 NumPy数据类型在Python和C之间映射,从而使我们可以使用NumPy数组而没有任何转换障碍。

    You can find the data type of a NumPy array by accessing the dtype property:

    您可以通过访问dtype属性来找到NumPy数组的数据类型:

    In [29]:

    在[29]中:

    wineswines .. dtype
    dtype
    

    Out[29]:

    出[29]:

    
    dtype('float64')
    

    NumPy has several different data types, which mostly map to Python data types, like float, and str. You can find a full listing of NumPy data types here, but here are a few important ones:

    NumPy有几种不同的数据类型,它们大多数都映射到Python数据类型,例如floatstr 。 您可以在此处找到NumPy数据类型的完整列表,但以下是一些重要的数据类型:

    • float – numeric floating point data.
    • int – integer data.
    • string – character data.
    • object – Python objects.
    • float数字浮点数据。
    • int –整数数据。
    • string –字符数据。
    • object – Python对象。

    Data types additionally end with a suffix that indicates how many bits of memory they take up. So int32 is a 32 bit integer data type, and float64 is a 64 bit float data type.

    数据类型还以一个后缀结尾,该后缀指示它们占用了多少内存。 因此, int32是32位整数数据类型,而float6464位float数据类型。

    转换数据类型 (Converting Data Types)

    You can use the numpy.ndarray.astype method to convert an array to a different type. The method will actually copy the array, and return a new array with the specified data type. For instance, we can convert wines to the int data type:

    您可以使用numpy.ndarray.astype方法将数组转换为其他类型。 该方法实际上将复制该数组,并返回具有指定数据类型的新数组。 例如,我们可以将wines转换为int数据类型:

    In [30]:

    在[30]中:

    Out[30]:

    出[30]:

    
    array([[ 7,  0,  0, ...,  0,  9,  5],
           [ 7,  0,  0, ...,  0,  9,  5],
           [ 7,  0,  0, ...,  0,  9,  5],
           ..., 
           [ 6,  0,  0, ...,  0, 11,  6],
           [ 5,  0,  0, ...,  0, 10,  5],
           [ 6,  0,  0, ...,  0, 11,  6]])
    
    

    As you can see above, all of the items in the resulting array are integers. Note that we used the Python int type instead of a NumPy data type when converting wines. This is because several Python data types, including float, int, and string, can be used with NumPy, and are automatically converted to NumPy data types.

    正如您在上面看到的,结果数组中的所有项目都是整数。 请注意,在转换wines时,我们使用Python int类型而不是NumPy数据类型。 这是因为NumPy可以使用包括floatintstring在内的几种Python数据类型,并将它们自动转换为NumPy数据类型。

    We can check the name property of the dtype of the resulting array to see what data type NumPy mapped the resulting array to:

    我们可以检查结果数组的dtypename属性,以查看NumPy将什么数据类型映射到结果数组:

    In [31]:

    在[31]中:

    int_wines int_wines = = wineswines .. astypeastype (( intint )
    )
    int_winesint_wines .. dtypedtype .. name
    name
    

    The array has been converted to a 64-bit integer data type. This allows for very long integer values, but takes up more space in memory than storing the values as 32-bit integers.

    该数组已转换为64位整数数据类型。 这允许很长的整数值,但是比将值存储为32位整数要占用更多的内存空间。

    If you want more control over how the array is stored in memory, you can directly create NumPy dtype objects like numpy.int32:

    如果要进一步控制数组在内存中的存储方式,可以直接创建NumPy dtype对象,例如numpy.int32

    Out[32]:

    出[32]:

    
    numpy.int32
    

    You can use these directly to convert between types:

    您可以直接使用它们在类型之间进行转换:

    In [33]:

    在[33]中:

    Out[33]:

    出[33]:

    
    array([[ 7,  0,  0, ...,  0,  9,  5],
           [ 7,  0,  0, ...,  0,  9,  5],
           [ 7,  0,  0, ...,  0,  9,  5],
           ..., 
           [ 6,  0,  0, ...,  0, 11,  6],
           [ 5,  0,  0, ...,  0, 10,  5],
           [ 6,  0,  0, ...,  0, 11,  6]], dtype=int32)
    
    

    NumPy阵列运算 (NumPy Array Operations)

    NumPy makes it simple to perform mathematical operations on arrays. This is one of the primary advantages of NumPy, and makes it quite easy to do computations.

    NumPy使在数组上执行数学运算变得简单。 这是NumPy的主要优点之一,并且使得进行计算非常容易。

    单数组数学 (Single Array Math)

    If you do any of the basic mathematical operations (/, *, -, +, ^) with an array and a value, it will apply the operation to each of the elements in the array.

    如果对数组和值执行任何基本数学运算( /*-+^ ),它将对数组中的每个元素应用该运算。

    Let’s say we want to add 10 points to each quality score because we’re drunk and feeling generous. Here’s how we’d do that:

    假设我们要为每个质量得分增加10分,因为我们喝醉了并且感觉很慷慨。 这是我们的处理方式:

    In [34]:

    在[34]中:

    wineswines [:,[:, 1111 ] ] + + 10
    10
    

    Out[34]:

    出[34]:

    
    array([ 15.,  15.,  15., ...,  16.,  15.,  16.])
    

    Note that the above operation won’t change the wines array – it will return a new 1-dimensional array where 10 has been added to each element in the quality column of wines.

    请注意,上述操作不会更改wines数组-它会返回一个新的1维数组,其中10添加到wines质量列中的每个元素。

    If we instead did +=, we’d modify the array in place:

    如果改为使用+= ,则会在适当的位置修改数组:

    In [35]:

    在[35]中:

    Out[35]:

    出[35]:

    
    array([ 15.,  15.,  15., ...,  16.,  15.,  16.])
    
    

    All the other operations work the same way. For example, if we want to multiply each of the quality score by 2, we could do it like this:

    所有其他操作都以相同的方式进行。 例如,如果我们想将每个质量得分乘以2 ,我们可以这样做:

    In [36]:

    在[36]中:

    wineswines [:,[:, 1111 ] ] * * 2
    2
    

    Out[36]:

    出[36]:

    
    array([ 30.,  30.,  30., ...,  32.,  30.,  32.])
    

    多数组数学 (Multiple Array Math)

    It’s also possible to do mathematical operations between arrays. This will apply the operation to pairs of elements. For example, if we add the quality column to itself, here’s what we get:

    在数组之间进行数学运算也是可能的。 这会将操作应用于成对的元素。 例如,如果我们向其自身添加quality列,则得到的是:

    In [38]:

    在[38]中:

    Out[38]:

    出[38]:

    
    array([ 10.,  10.,  10., ...,  12.,  10.,  12.])
    
    

    Note that this is equivalent to wines[11] * 2 – this is because NumPy adds each pair of elements. The first element in the first array is added to the first element in the second array, the second to the second, and so on.

    请注意,这等效于wines[11] * 2 –这是因为NumPy添加了每对元素。 将第一个数组中的第一个元素添加到第二个数组中的第一个元素,第二个添加到第二个,依此类推。

    We can also use this to multiply arrays. Let’s say we want to pick a wine that maximizes alcohol content and quality (we want to get drunk, but we’re classy). We’d multiply alcohol by quality, and select the wine with the highest score:

    我们还可以使用它来乘法数组。 假设我们要挑选一种酒,使酒精含量和质量达到最高(我们想喝醉,但我们很优雅)。 我们将alcohol乘以quality ,然后选择得分最高的葡萄酒:

    In [39]:

    在[39]中:

    wineswines [:,[:, 1010 ] ] * * wineswines [:,[:, 1111 ]
    ]
    

    Out[39]:

    出[39]:

    
    array([ 47.,  49.,  49., ...,  66.,  51.,  66.])
    

    All of the common operations (/, *, -, +, ^) will work between arrays.

    所有常见的操作( /*-+^ )将在数组之间工作。

    广播 (Broadcasting)

    Unless the arrays that you’re operating on are the exact same size, it’s not possible to do elementwise operations. In cases like this, NumPy performs broadcasting to try to match up elements. Essentially, broadcasting involves a few steps:

    除非您要操作的数组的大小完全相同,否则无法进行元素操作。 在这种情况下,NumPy执行广播以尝试匹配元素。 本质上,广播涉及几个步骤:

    • The last dimension of each array is compared.
      • If the dimension lengths are equal, or one of the dimensions is of length 1, then we keep going.
      • If the dimension lengths aren’t equal, and none of the dimensions have length 1, then there’s an error.
    • Continue checking dimensions until the shortest array is out of dimensions.
    • 比较每个数组的最后一个维度。
      • 如果尺寸长度相等,或者其中一个尺寸长度为1 ,那么我们继续前进。
      • 如果尺寸长度不相等,并且所有尺寸都不具有长度1 ,则存在错误。
    • 继续检查尺寸,直到最短的数组超出尺寸为止。

    For example, the following two shapes are compatible:

    例如,以下两个形状是兼容的:

    This is because the length of the trailing dimension of array A is 3, and the length of the trailing dimension of array B is 3. They’re equal, so that dimension is okay. Array B is then out of elements, so we’re okay, and the arrays are compatible for mathematical operations.

    这是因为数组A的尾随尺寸的长度为3 ,而数组B的尾随尺寸的长度为3 。 它们是相等的,所以尺寸是可以的。 然后数组B的元素不足,所以我们可以了,并且这些数组可用于数学运算。

    The following two shapes are also compatible:

    以下两个形状也兼容:

    A: (1,2)
    B  (50,2)
    
    A: (1,2)
    B  (50,2)
    
    

    The last dimension matches, and A is of length 1 in the first dimension.

    最后一个尺寸匹配,并且在第一个尺寸中A的长度为1

    These two arrays don’t match:

    这两个数组不匹配:

    The lengths of the dimensions aren’t equal, and neither array has either dimension length equal to 1.

    维度的长度不相等,两个数组的维度长度都不等于1

    There’s a detailed explanation of broadcasting here, but we’ll go through a few examples to illustrate the principle:

    有广播的详细说明在这里 ,但我们将通过几个例子来说明这样的原则:

    In [40]:

    在[40]中:

    wines wines * * npnp .. arrayarray ([([ 11 ,, 22 ])
    ])
    

    The above example didn’t work because the two arrays don’t have a matching trailing dimension. Here’s an example where the last dimension does match:

    上面的示例不起作用,因为两个数组没有匹配的尾随尺寸。 这是最后一个尺寸匹配的示例:

    In [72]:

    在[72]中:

    array_one array_one = = npnp .. arrayarray (
        (
        [
            [
            [[ 11 ,, 22 ],
            ],
            [[ 33 ,, 44 ]
        ]
        ]
    ]
    )
    )
    array_two array_two = = npnp .. arrayarray ([([ 44 ,, 55 ])
    
    ])
    
    array_one array_one + + array_two
    array_two
    

    Out[72]:

    出[72]:

    
    array([[5, 7],
           [7, 9]])
    

    As you can see, array_two has been broadcasted across each row of array_one. Here’s an example with our wines data:

    如您所见, array_two已在array_two每一行中array_one 。 这是我们的wines数据示例:

    In [41]:

    在[41]中:

    Out[41]:

    出[41]:

    
    array([[  8.08375389,   0.89047394,   0.77022918, ...,   0.94917479,
             10.34668852,   5.34569289],
           [  8.48375389,   1.07047394,   0.77022918, ...,   1.06917479,
             10.74668852,   5.34569289],
           [  8.48375389,   0.95047394,   0.81022918, ...,   1.03917479,
             10.74668852,   5.34569289],
           ..., 
           [  6.98375389,   0.70047394,   0.90022918, ...,   1.13917479,
             11.94668852,   6.34569289],
           [  6.58375389,   0.83547394,   0.89022918, ...,   1.09917479,
             11.14668852,   5.34569289],
           [  6.68375389,   0.50047394,   1.24022918, ...,   1.04917479,
             11.94668852,   6.34569289]])
    
    

    Elements of rand_array are broadcast over each row of wines, so the first column of wines has the first value in rand_array added to it, and so on.

    的元件rand_array被超过的每一行广播wines ,所以第一列wines具有在第一值rand_array添加到它,等等。

    喜欢这篇文章吗? 使用Dataquest学习数据科学! (Enjoying this post? Learn data science with Dataquest!)

    • Learn from the comfort of your browser.
    • Work with real-life data sets.
    • Build a portfolio of projects.
    • 从舒适的浏览器中学习。
    • 处理实际数据集。
    • 建立项目组合。

    NumPy数组方法 (NumPy Array Methods)

    In addition to the common mathematical operations, NumPy also has several methods that you can use for more complex calculations on arrays. An example of this is the numpy.ndarray.sum method. This finds the sum of all the elements in an array by default:

    除了常见的数学运算之外,NumPy还提供了几种方法,可用于对数组进行更复杂的计算。 numpy.ndarray.sum方法就是一个例子。 默认情况下,这将查找数组中所有元素的总和:

    In [42]:

    在[42]中:

    wineswines [:,[:, 1111 ]] .. sumsum ()
    ()
    

    The total of all of our quality ratings is 154.1788. We can pass the axis keyword argument into the sum method to find sums over an axis. If we call sum across the wines matrix, and pass in axis=0, we’ll find the sums over the first axis of the array. This will give us the sum of all the values in every column. This may seem backwards that the sums over the first axis would give us the sum of each column, but one way to think about this is that the specified axis is the one “going away”. So if we specify axis=0, we want the rows to go away, and we want to find the sums for each of the remaining axes across each row:

    我们所有的质量154.1788154.1788 。 我们可以将axis关键字参数传递给sum方法,以查找轴上的总和。 如果我们在wines矩阵中调用sum ,并在axis=0传递,我们将在数组的第一个轴上找到sum。 这将为我们提供每一列中所有值的总和。 这似乎倒退了,第一条轴上的总和将提供每一列的总和,但是考虑这一点的一种方法是指定的轴是“离开”的那条轴。 因此,如果我们指定axis=0 ,我们希望各行消失,并希望找到每一行中其余各轴的总和:

    In [43]:

    在[43]中:

    Out[43]:

    出[43]:

    
    array([ 13303.1    ,    843.985  ,    433.29   ,   4059.55   ,
              139.859  ,  25384.     ,  74302.     ,   1593.79794,
             5294.47   ,   1052.38   ,  16666.35   ,   9012.     ])
    
    

    We can verify that we did the sum correctly by checking the shape. The shape should be 12, corresponding to the number of columns:

    我们可以通过检查形状来验证我们正确地做了和。 形状应为12 ,对应于列数:

    In [44]:

    在[44]中:

    wineswines .. sumsum (( axisaxis == 00 )) .. shape
    shape
    

    If we pass in axis=1, we’ll find the sums over the second axis of the array. This will give us the sum of each row:

    如果传入axis=1 ,我们将找到数组第二个轴的总和。 这将给我们每一行的总和:

    In [45]:

    在[45]中:

    Out[45]:

    出[45]:

    
    array([  74.5438 ,  123.0548 ,   99.699  , ...,  100.48174,  105.21547,
             92.49249])
    
    

    There are several other methods that behave like the sum method, including:

    其他几种方法的行为类似于sum方法,包括:

    You can find a full list of array methods here.

    您可以在此处找到数组方法的完整列表。

    NumPy数组比较 (NumPy Array Comparisons)

    NumPy makes it possible to test to see if rows match certain values using mathematical comparison operations like <, >, >=, <=, and ==. For example, if we want to see which wines have a quality rating higher than 5, we can do this:

    NumPy使得可以使用数学比较操作(例如<>>=<===测试行是否与某些值匹配。 例如,如果我们想查看哪些葡萄酒的质量等级高于5 ,我们可以这样做:

    In [46]:

    在[46]中:

    wineswines [:,[:, 1111 ] ] > > 5
    5
    

    Out[46]:

    出[46]:

    
    array([False, False, False, ...,  True, False,  True], dtype=bool)
    

    We get a Boolean array that tells us which of the wines have a quality rating greater than 5. We can do something similar with the other operators. For instance, we can see if any wines have a quality rating equal to 10:

    我们得到一个布尔数组,该布尔数组告诉我们哪些葡萄酒的质量评级大于5 。 我们可以和其他运营商做类似的事情。 例如,我们可以查看是否有任何葡萄酒的质量评级等于10

    In [47]:

    在[47]中:

    Out[47]:

    出[47]:

    
    array([False, False, False, ..., False, False, False], dtype=bool)
    
    

    子集 (Subsetting)

    One of the powerful things we can do with a Boolean array and a NumPy array is select only certain rows or columns in the NumPy array. For example, the below code will only select rows in wines where the quality is over 7:

    我们可以使用布尔数组和NumPy数组执行的强大功能之一是仅选择NumPy数组中的某些行或列。 例如,以下代码将仅选择质量超过7 wines中的行:

    In [64]:

    在[64]中:

    high_quality high_quality = = wineswines [:,[:, 1111 ] ] > > 7
    7
    wineswines [[ high_qualityhigh_quality ,:][:,:][: 33 ,:]
    ,:]
    

    Out[64]:

    出[64]:

    
    array([[  7.90000000e+00,   3.50000000e-01,   4.60000000e-01,
              3.60000000e+00,   7.80000000e-02,   1.50000000e+01,
              3.70000000e+01,   9.97300000e-01,   3.35000000e+00,
              8.60000000e-01,   1.28000000e+01,   8.00000000e+00],
           [  1.03000000e+01,   3.20000000e-01,   4.50000000e-01,
              6.40000000e+00,   7.30000000e-02,   5.00000000e+00,
              1.30000000e+01,   9.97600000e-01,   3.23000000e+00,
              8.20000000e-01,   1.26000000e+01,   8.00000000e+00],
           [  5.60000000e+00,   8.50000000e-01,   5.00000000e-02,
              1.40000000e+00,   4.50000000e-02,   1.20000000e+01,
              8.80000000e+01,   9.92400000e-01,   3.56000000e+00,
              8.20000000e-01,   1.29000000e+01,   8.00000000e+00]])
    

    We select only the rows where high_quality contains a True value, and all of the columns. This subsetting makes it simple to filter arrays for certain criteria. For example, we can look for wines with a lot of alcohol and high quality. In order to specify multiple conditions, we have to place each condition in parentheses, and separate conditions with an ampersand (&):

    我们仅选择high_quality包含True值的行以及所有列。 通过此子集,可以轻松地根据特定条件过滤阵列。 例如,我们可以寻找含有大量酒精和高品质的葡萄酒。 为了指定多个条件,我们必须把括号每个条件,独立的条件与符号( & ):

    In [63]:

    在[63]中:

    Out[63]:

    出[63]:

    
    array([[ 12.8,   8. ],
           [ 12.6,   8. ],
           [ 12.9,   8. ],
           [ 13.4,   8. ],
           [ 11.7,   8. ],
           [ 11. ,   8. ],
           [ 11. ,   8. ],
           [ 14. ,   8. ],
           [ 12.7,   8. ],
           [ 12.5,   8. ],
           [ 11.8,   8. ],
           [ 13.1,   8. ],
           [ 11.7,   8. ],
           [ 14. ,   8. ],
           [ 11.3,   8. ],
           [ 11.4,   8. ]])
    
    

    We can combine subsetting and assignment to overwrite certain values in an array:

    我们可以结合使用子集和赋值来覆盖数组中的某些值:

    In [50]:

    在[50]中:

    high_quality_and_alcohol high_quality_and_alcohol = = (( wineswines [:,[:, 1010 ] ] > > 1010 ) ) & & (( wineswines [:,[:, 1111 ] ] > > 77 )
    )
    wineswines [[ high_quality_and_alcoholhigh_quality_and_alcohol ,, 1010 :] :] = = 20
    20
    

    重塑NumPy数组 (Reshaping NumPy Arrays)

    We can change the shape of arrays while still preserving all of their elements. This often can make it easier to access array elements. The simplest reshaping is to flip the axes, so rows become columns, and vice versa. We can accomplish this with the numpy.transpose function:

    我们可以更改数组的形状,同时保留所有元素。 这通常可以使访问数组元素更加容易。 最简单的重塑是翻转轴,因此行变成列,反之亦然。 我们可以使用numpy.transpose函数完成此操作

    In [51]:

    在[51]中:

    Out[51]:

    出[51]:

    
    (12, 1599)
    
    

    We can use the numpy.ravel function to turn an array into a one-dimensional representation. It will essentially flatten an array into a long sequence of values:

    我们可以使用numpy.ravel函数将数组转换为一维表示形式。 它将本质上将数组平整为一长串值:

    In [52]:

    在[52]中:

    wineswines .. ravelravel ()
    ()
    

    Out[52]:

    出[52]:

    
    array([  7.4 ,   0.7 ,   0.  , ...,   0.66,  11.  ,   6.  ])
    

    Here’s an example where we can see the ordering of numpy.ravel:

    这是一个示例,我们可以看到numpy.ravel的顺序:

    In [73]:

    在[73]中:

    Out[73]:

    出[73]:

    
    array([1, 2, 3, 4, 5, 6, 7, 8])
    
    

    Finally, we can use the numpy.reshape function to reshape an array to a certain shape we specify. The below code will turn the second row of wines into a 2-dimensional array with 2 rows and 6 columns:

    最后,我们可以使用numpy.reshape函数将数组重塑为我们指定的特定形状。 下面的代码将把第二行wines变成具有26列的二维数组:

    In [53]:

    在[53]中:

    wineswines [[ 11 ,:],:] .. reshapereshape (((( 22 ,, 66 ))
    ))
    

    Out[53]:

    出[53]:

    
    array([[  7.8   ,   0.88  ,   0.    ,   2.6   ,   0.098 ,  25.    ],
           [ 67.    ,   0.9968,   3.2   ,   0.68  ,   9.8   ,   5.    ]])
    

    结合NumPy数组 (Combining NumPy Arrays)

    With NumPy, it’s very common to combine multiple arrays into a single unified array. We can use numpy.vstack to vertically stack multiple arrays. Think of it like the second arrays’s items being added as new rows to the first array. We can read in the winequality-white.csv dataset that contains information on the quality of white wines, then combine it with our existing dataset, wines, which contains information on red wines.

    使用NumPy,将多个数组组合成一个统一的数组非常普遍。 我们可以使用numpy.vstack垂直堆叠多个数组。 可以将第二个数组的项作为新行添加到第一个数组中。 我们可以读取winequality-white.csv数据集,其中包含有关白葡萄酒的质量的信息,然后将其与我们现有的数据集wines ,其中包含有关红葡萄酒的信息。

    In the below code, we:

    在下面的代码中,我们:

    • Read in winequality-white.csv.
    • Display the shape of white_wines.
    • 阅读winequality-white.csv
    • 显示white_wines的形状。

    In [55]:

    在[55]中:

    Out[55]:

    出[55]:

    
    (4898, 12)
    
    

    As you can see, we have attributes for 4898 wines. Now that we have the white wines data, we can combine all the wine data.

    如您所见,我们有4898葡萄酒的属性。 现在我们有了白葡萄酒数据,我们可以合并所有葡萄酒数据。

    In the below code, we:

    在下面的代码中,我们:

    • Use the vstack function to combine wines and white_wines.
    • Display the shape of the result.
    • 使用vstack函数将wineswhite_wines结合在一起。
    • 显示结果的形状。

    In [56]:

    在[56]中:

    all_wines all_wines = = npnp .. vstackvstack (((( wineswines , , white_wineswhite_wines ))
    ))
    all_winesall_wines .. shape
    shape
    

    Out[56]:

    出[56]:

    
    (6497, 12)
    

    As you can see, the result has 6497 rows, which is the sum of the number of rows in wines and the number of rows in red_wines.

    如您所见,结果有6497行,这是wines中行数和red_wines数的red_wines

    If we want to combine arrays horizontally, where the number of rows stay constant, but the columns are joined, then we can use the numpy.hstack function. The arrays we combine need to have the same number of rows for this to work.

    如果我们想水平合并数组,使行数保持不变,但将列连接在一起 ,则可以使用numpy.hstack函数。 我们组合的数组需要具有相同的行数才能起作用。

    Finally, we can use numpy.concatenate as a general purpose version of hstack and vstack. If we want to concatenate two arrays, we pass them into concatenate, then specify the axis keyword argument that we want to concatenate along. Concatenating along the first axis is similar to vstack, and concatenating along the second axis is similar to hstack:

    最后,我们可以将numpy.concatenate用作hstackvstack通用版本。 如果要串联两个数组,可以将它们传递给concatenate ,然后指定要串联的axis关键字参数。 沿第一个轴的连接类似于vstack ,沿第二个轴的连接类似于hstack

    In [57]:

    在[57]中:

    Out[57]:

    出[57]:

    
    array([[  7.4 ,   0.7 ,   0.  , ...,   0.56,   9.4 ,   5.  ],
           [  7.8 ,   0.88,   0.  , ...,   0.68,   9.8 ,   5.  ],
           [  7.8 ,   0.76,   0.04, ...,   0.65,   9.8 ,   5.  ],
           ..., 
           [  6.5 ,   0.24,   0.19, ...,   0.46,   9.4 ,   6.  ],
           [  5.5 ,   0.29,   0.3 , ...,   0.38,  12.8 ,   7.  ],
           [  6.  ,   0.21,   0.38, ...,   0.32,  11.8 ,   6.  ]])
    
    

    进一步阅读 (Further Reading)

    You should now have a good grasp of NumPy, and how to apply it to a data set.

    现在,您应该对NumPy有很好的了解,以及如何将其应用于数据集。

    If you want to dive into more depth, here are some resources that may be helpful:

    如果您想深入研究,以下一些资源可能会有所帮助:

    • You can’t mix multiple data types in an array.
    • You have to remember what type of data each column contains.
    • 您不能在数组中混合使用多种数据类型。
    • 您必须记住每列包含的数据类型。

    翻译自: https://www.pybloggers.com/2016/10/numpy-tutorial-data-analysis-with-python/

    展开全文
  • python numpy 终极指南 (ULTIMATE GUIDE) Numpy (which stands for Numerical Python) is a library available in Python programming language, supporting matrix data structures and multidimensional array ...

    python numpy

    终极指南 (ULTIMATE GUIDE)

    Numpy (which stands for Numerical Python) is a library available in Python programming language, supporting matrix data structures and multidimensional array objects. This the most basic scientific computing library that we need to learn, to begin our journey in the field of data science.

    Numpy( 代表 Numeric Python )是一个可用Python编程语言提供的库,支持矩阵数据结构和多维数组对象。 这是我们需要学习的最基本的科学计算库,以开始我们在数据科学领域的旅程。

    Numpy can compute basic mathematical calculations to make the process of creating advanced machine learning and artificial intelligence applications easier (by using comprehensive mathematical functions available within the library). Numpy allows us to carry out various complex mathematical calculations effortlessly along with several top-up libraries (like matplotlib, pandas, scikit-learn, etc.) built over it.

    Numpy可以计算基本的数学计算 ,从而简化创建高级机器学习和人工智能应用程序的过程(通过使用库中提供的全面数学函数)。 Numpy允许我们轻松地进行各种复杂的数学计算,以及在其上构建的数个充值库(例如matplotlib,pandas,scikit-learn等)。

    This library is a great tool for every data science professional to handle and analyze the data efficiently. Moreover, it is much easier to perform mathematical operations with numpy arrays in comparison to python’s list.

    该库是每位数据科学专业人员有效处理和分析数据的好工具。 而且,与python的列表相比,使用numpy数组执行数学运算要容易得多。

    Numpy library has various functions available in it. In this article, we will learn some essential and lesser-known functions of this library and how to implement them efficiently.

    Numpy库具有各种可用功能。 在本文中,我们将学习该库的一些基本 功能鲜为人知的功能,以及如何有效地实现它们。

    Note: In this article, we will be using Google Colaboratory to execute our codes.

    注意:在本文中,我们将使用 Google Colaboratory 执行代码。

    导入numpy (Importing numpy)

    Numpy can be simply imported in the notebook by using the following code:

    可以使用以下代码将Numpy轻松导入笔记本中:

    import numpy as np

    Here, numpy is written as np to save time while coding, and also it is a de facto in the data science community.

    在这里,numpy被编写为np以节省编码时的时间,并且它在数据科学界实际上是事实。

    Now, let’s get started with numpy functions!

    现在,让我们开始使用numpy函数!

    使用numpy创建n维数组 (Creation of n-dimensional array using numpy)

    An array is a data structure in the numpy library, which is just like a list which can store values, but the differences are that we can specify the data type of elements of an array ( dtype function) and arrays are faster and take less memory to store data, allowing the code to be optimized even further.

    数组是numpy库中的数据结构,就像可以存储值的列表一样,但是区别在于我们可以指定数组元素的数据类型( dtype函数),并且数组速度更快,占用的内存更少存储数据,从而可以进一步优化代码。

    To create a single-dimensional array we can use the following code:

    要创建一维数组,我们可以使用以下代码:

    import numpy as np
    array = np.array([1,2,3,4,5])

    The process for creating a multi-dimensional array is similar, we just have to add more values in []brackets:

    创建多维数组的过程 相似,我们只需要在[]括号中添加更多值:

    array = np.array([[1.1,2.2,3.0,4.6,5.0],[6.4,7.3,8.5,9.1,10.2])

    numpy.linsapce()函数 (numpy.linsapce() function)

    This numpy.linspace() function is used to create an array of evenly spaced numbers in a given interval. We can also determine the number of samples we want to generate (however, it is an optional parameter default value is set to fifty samples). Another optional parameter we can add to this function is restep which if True will return the space i.e. spacing between the samples along with the list. The function is: numpy.linspace(start, stop). Let’s apply this function in an example:

    numpy.linspace()函数用于在给定间隔中创建均匀间隔的数字数组。 我们还可以确定要生成的样本数(但是,这是一个可选参数,默认值设置为五十个样本)。 我们可以添加到此函数的另一个可选参数是restep ,如果为True则将返回space即样本与列表之间的间隔。 该函数是: numpy.linspace(start, stop) 。 让我们在示例中应用此功能:

    import numpy as np
    import matplotlib.pyplot as plt
    x = np.linspace(0,10,10,dtype = int, retstep=True)
    print(x)
    x = np.linspace(0,10,100)
    y = np.sin(x)
    plt.plot(x,y,color = 'orange')
    plt.show()

    As we can see here, even to calculate mathematical functions we are using numpy library. We used the linspace() function to generate equally spaced values and used that array to plot sine function plot.

    正如我们在这里看到的,即使要计算数学函数,我们也使用numpy库。 我们使用linspace()函数生成等距的值,并使用该数组绘制sine函数图。

    sine function graph| linspace() function numpy
    Author) 作者提供的图像) sine function graph using linspace() function to generate values 使用linspace()函数生成值的正弦函数图

    随机采样功能 (Function for random sampling)

    Here, thenumpy.random function helps us calculate random values in various ways like generating random values in a given shape, generating an array by randomly selecting values from a given 1D array, or randomly permute a sequence of a given array or a range.

    在这里, numpy.random函数可以帮助我们以各种方式计算随机值,例如以给定形状生成随机值,通过从给定的1D数组中随机选择值来生成数组或随机排列给定数组或范围的序列。

    • numpy.random.rand(): With this function, we can create an array of uniformly distributed values over given input shape in a range [0,1) (i.e. ‘1’ is excluded). For example:

      numpy.random.rand():使用此函数,我们可以在给定的输入形状上创建一个范围为[0,1](即排除“ 1”)的均匀分布值的数组。 例如:

    np.random.rand(3,4)

    As we can see in this example, an array of shape (3,4) is generated with all values lying in a range of [0,1).

    正如我们在本例中看到的,将生成一个形状为(3,4)的数组,所有值都在[0,1)范围内。

    Numpy random function
    Author) 作者提供 ) Generating random values 生成随机值
    • numpy.random.choice(): This random function returns an array of random samples from a given input array. Other optional parameters that we can define are- size i.e. the output shape of the array, replace i.e. whether we want repeated values in our output array and p i.e. probability for each given sample of the input array. Check out the following example:

      numpy.random.choice():此随机函数从给定的输入数组返回一个随机样本数组。 其它可选参数,我们可以定义为─ size即阵列的输出的形状, replace即我们是否要重复的值在我们的输出阵列和p即概率为输入阵列的每个给定的样本。 查看以下示例:

    np.random.choice([1,2,3,4],(1,2,3),replace=True,p=[0.2,0.1,0.4,0.3])

    Here, we have given the following input parameters to the functions- an input array with four elements, shape of output array ( 1 in the above code is the numbers of the arrays we want as output and 2,3 is output shape), repetition of values is True and probability for each sample (where the sum of values should be equal to one).

    在这里,我们为函数提供了以下输入参数-具有四个元素的输入数组,输出数组的形状(以上代码中的1是我们想要作为输出的数组的编号,而2,3是输出形状),重复的值是True ,是每个样本的概率(其中值的总和应等于1)。

    Random sampling | numpy python
    Author) 作者提供 ) Random sampling using numpy.random.choice() 使用numpy.random.choice()随机抽样
    • np.random.permutation(): This function returns an array with a randomly permutated sequence (in case of input array) or a permuted range (in case of single-input).

      np.random.permutation():此函数返回一个数组,该数组具有随机排列的序列(对于输入数组)或排列范围(对于单输入)。

    arr = np.random.permutation(5)
    print('Permutation of a range: ' + str(arr))
    arr_ = np.random.permutation([1,2,3,4,5,6,7,8,9])
    print('Permutation of elements of input array: ' + str(arr_))

    In the first case, we have returned a permuted array over an input range and in the second case, we have returned a permuted array over an input array.

    在第一种情况下,我们在输入范围内返回了一个排列的数组,在第二种情况下,我们在输入数组上返回了一个排列的数组。

    Random permutation using numpy
    Author) 作者提供 ) Random permutation using numpy 使用numpy进行随机排列

    The functions available in the numpy.random are not only limited to these, but you can also find the complete exhaustive list of functions here: numpy documentation page.

    numpy.random中可用的功能不仅限于这些,还可以在以下位置找到完整的功能清单: numpy文档页面

    数组的索引和切片 (Indexing and slicing of an array)

    To access and modify the objects of an array, we use indexing and slicing methods. Index values of the first element in the array of length n, start from 0 value and index for the last element of the array will be n-1 .

    要访问和修改数组的对象,我们使用索引和切片方法。 长度为n的数组中第一个元素的索引值从0值开始,数组最后一个元素的索引为n-1

    a = [1,2,3,4,5,6]
    b = a[3]
    #output = 4

    In the above example, this indexing method will return the fourth element of the array a.

    在上面的示例中,此索引方法将返回数组a.的第四个元素a.

    For basic slicing of the array (i.e. splitting the array, in simple words), we use [start:stop:step_size] notation.

    对于数组的基本切片(即简单地拆分数组),我们使用[start:stop:step_size]表示法。

    arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]arr[1:7:2]
    #output array([1, 3, 5])

    Advanced indexing and slicing: For a multi-dimensional array, we can index and slice the array by giving input of specific rows and columns values( in [rows,column] format). For better understanding check the following example:

    高级索引和切片:对于多维数组,我们可以通过输入特定的行和列值(以[rows,column]格式)来对数组进行索引和切片。 为了更好地理解,请检查以下示例:

    x = np.array([[ 0,  1,  2],
    [ 3, 4, 5],
    [ 6, 7, 8]])x[0:2,1:2]

    Here, we have chosen the index of the first two rows (i.e. 0:2 in code) and a single column with index 1 (i.e. 1:2 in code).

    在这里,我们选择了前两行的索引(即代码中的0:2 )和具有索引1 (即代码中的1:2 )的单列。

    Advanced indexing and slicing numpy
    Author) 作者提供 ) Advanced indexing and slicing 高级索引和切片

    numpy.ravel()和numpy.flatten()函数 (numpy.ravel() and numpy.flatten() functions)

    These functions return a 1D flattened form of the input array.

    这些函数返回输入数组的一维展平形式。

    arr = np.array([[1,2], [3,4],[5,6]])
    x = arr.flatten()
    print(x)
    y = arr.ravel()
    print(y)
    The output of the above code | numpy
    Author) 作者提供的图片) The output of the above code 上面代码的输出

    You may observe that the output of both functions is the same! Now you might wonder what is the difference between the two functions as their output result is the same. It’s simple in numpy.flatten() a copy of the original array is created while in numpy.ravel() the original array is changed. Moreover, numpy.ravel() function is faster than numpy.flatten()as it does not occupy any memory.

    您可能会发现两个函数的输出是相同的! 现在您可能想知道这两个函数之间的区别是什么,因为它们的输出结果是相同的。 在numpy.flatten()中创建原始数组的副本很简单,而在numpy.ravel()中更改原始数组则很简单。 而且, numpy.ravel()函数比numpy.flatten()更快,因为它不占用任何内存。

    numpy.isclose()函数 (numpy.isclose() function)

    This function is used to check whether two arrays are equal elements wise within tolerance and returns a boolean array. .isclosefunction array can be used to assert(verify) your code.

    此函数用于检查两个数组在公差范围内是否等于相等的元素,并返回布尔数组。 .isclose函数数组可用于assert (验证)您的代码。

    def inv(arr):
    arr = np.array(arr)
    inverse = np.linalg.inv(arr)
    return inverseassert np.all(np.isclose(inv(np.array([[6, 1, 1], [4, -2, 5], [2, 8, 7]])).tolist(),np.array([[0.17647058823529413,-0.0032679738562091526, -0.02287581699346405],[0.05882352941176469, -0.130718954248366, 0.0849673202614379],[-0.1176470588235294, 0.1503267973856209, 0.0522875816993464]])))print("Sample Tests passed", '\U0001F44D')

    In this above, example we are finding the inverse of a given matrix using another numpy function numpy.linalg.inv() . After that we are verifying are result using assertfunction and we have used numpy.isclose() function to check the output values if they are close to the true values. The assert function will only work if all the values are True otherwise it will give an assertion error.

    在上面的示例中,我们使用另一个numpy函数numpy.linalg.inv()查找给定矩阵的逆。 之后,我们使用assert函数验证结果,并使用numpy.isclose()函数检查输出值是否接近真实值。 assert函数仅在所有值均为True时才起作用,否则会给出断言错误。

    Implementation of .isclose() function | numpy
    Author) 作者提供的图片) Implementation of .isclose() function .isclose()函数的实现

    在numpy中堆叠数组 (Stack arrays in numpy)

    There are two functions available in numpy for stacking different arrays.

    numpy中有两个函数可用于堆叠不同的数组。

    • numpy.hstack(): this function stacks the arrays column-wise (i.e. horizontally), similar to the concatenation of arrays along the second axis (except 1D array, where it concatenates along the first axis). For this function, the input arrays should be of the same shape (except 1D arrays, which can be of any length).

      numpy.hstack():此函数按列(即,水平)堆叠数组,类似于沿第二个轴的数组串联(一维数组除外,它沿第一个轴串联)。 对于此功能,输入数组应具有相同的形状(一维数组除外,该数组可以是任意长度)。

    a = np.array([[1,2],[3,4],[5,6]])
    b = np.array([[7,8],[9,10],[11,12]])np.hstack((a,b))
    Horizontal stacking of arrays using .hstack() function
    Author) 作者提供 ) Horizontal stacking of arrays using .hstack() function 使用.hstack()函数水平堆叠数组

    numpy.vstack(): this function stacks the arrays row-wise (i.e. vertically), similar to the concatenation of arrays along the first axis after 1-D arrays of shape (N,) have been reshaped to (1, N). For this function, the input arrays should be of the same shape (1D arrays must have the same length).

    numpy.vstack():此函数按行(即垂直)堆叠数组,类似于将形状(N,)的1-D数组重塑为(1,N)后沿第一轴的数组连接。 对于此功能,输入数组应具有相同的形状(一维数组必须具有相同的长度)。

    a = np.array([[1,2],[3,4],[5,6]])
    b = np.array([[7,8],[9,10],[11,12]])np.vstack((a,b))
    Vertical stacking of arrays using .vstack() function | Numpy
    Author) 作者提供的图片) Vertical stacking of arrays using .vstack() function 使用.vstack()函数的垂直堆叠数组

    numpy的统计功能 (Statistics functions of numpy)

    Numpy library has some useful functions for finding insights and analyzing the data statistically. We can calculate mean, median, variance, standard deviation, compute histogram over a set of data, and much more.

    Numpy库具有一些有用的功能,可用于发现见解并进行统计分析。 我们可以计算平均值,中位数,方差,标准差,计算一组数据的直方图等等。

    • numpy.mean(): with this function, we can calculate the arithmetic mean of a given array where we can also specify the axis.

      numpy.mean():使用此函数,我们可以计算给定数组的算术平均值,也可以在其中指定轴。

    arr = a = np.array([[1, 2], [3, 4]])
    np.mean(a,axis=1)#output:
    array([1.5, 3.5])
    • numpy.histogram(): this function helps us compute the histogram over a set of data. Here, we have to input a flattened array of data over which we want to compute the histogram, we can also define the number of bins (i.e. number of equal-width bins in a given range (optional)), and range of upper limit and limit of the bins (optional).

      numpy.histogram():此函数可帮助我们计算一组数据的直方图。 在这里,我们必须输入一个扁平的上我们想要计算直方图数据的阵列中,我们也可以定义的数目bins (即,等于宽度箱中的给定范围(可选)的数),和range的上限和垃圾箱的限制(可选)。

    arr = np.array([1,2,3,2,2,3,4,5])
    np.histogram(arr, bins= [1,2,3,4,5])
    Computing histogram using numpy
    Author) 作者提供 ) Computing histogram using numpy 使用numpy计算直方图

    You can also visualize this histogram values on a plot using the matplotlib library.

    您还可以使用matplotlib库在图表上可视化此直方图值。

    You can find other numpy statistics functions here: numpy documentation page.

    您可以在以下位置找到其他numpy统计功能: numpy文档页面

    结论 (Conclusion)

    I hope with this article you must have learned some essential and new functions of this library. I would recommend you to try implementing these functions on your own for a better understanding.

    我希望通过本文,您一定已经学习了该库的一些基本功能和新功能。 我建议您尝试自己实现这些功能,以更好地理解。

    Implementing these skills in daily use will definitely benefit you as a data science professional!

    在日常使用中实施这些技能绝对可以使您成为数据科学专业人士!

    If you have any questions or comments, please post them in the comment section.

    如果您有任何问题或意见,请在评论部分中发布。

    If you want to learn how to visualize the data and find the insights from it visually, then check out our another article:

    如果您想学习如何可视化数据并直观地从中找到见解,请查看我们的另一篇文章:

    Originally published at: www.patataeater.blogspot.com

    最初发布于: www.patataeater.blogspot.com

    翻译自: https://towardsdatascience.com/numpy-cheatsheet-for-essential-functions-python-2e7d8618d688

    python numpy

    展开全文
  • 它不仅是Python中使用最多的第三方库,而且还是SciPy、Pandas等数据科学的基础库。它所提供的数据结构比Python自身的“更高级、更高效”,可以这么说,NumPy所提供的数据结构是Python数据分析的基础。 我上次讲到了...

    Python科学计算:用NumPy快速处理数据

    Python中一个非常重要的第三方库就是NumPy。

    它不仅是Python中使用最多的第三方库,而且还是SciPy、Pandas等数据科学的基础库。它所提供的数据结构比Python自身的“更高级、更高效”,可以这么说,NumPy所提供的数据结构是Python数据分析的基础。

    我上次讲到了Python数组结构中的列表list,它实际上相当于一个数组的结构。而NumPy中一个关键数据类型就是关于数组的,那为什么还存在这样一个第三方的数组结构呢?

    实际上,标准的Python中,用列表list保存数组的数值。由于列表中的元素可以是任意的对象,所以列表中list保存的是对象的指针。虽然在Python编程中隐去了指针的概念,但是数组有指针,Python的列表list其实就是数组。这样如果我要保存一个简单的数组[0,1,2],就需要有3个指针和3个整数的对象,这样对于Python来说是非常不经济的,浪费了内存和计算时间。

    使用NumPy让你的Python科学计算更高效

    为什么要用NumPy数组结构而不是Python本身的列表list?这是因为列表list的元素在系统内存中是分散存储的,而NumPy数组存储在一个均匀连续的内存块中。这样数组计算遍历所有的元素,不像列表list还需要对内存地址进行查找,从而节省了计算资源。

    另外在内存访问模式中,缓存会直接把字节块从RAM加载到CPU寄存器中。因为数据连续的存储在内存中,NumPy直接利用现代CPU的矢量化指令计算,加载寄存器中的多个连续浮点数。另外NumPy中的矩阵计算可以采用多线程的方式,充分利用多核CPU计算资源,大大提升了计算效率。

    当然除了使用NumPy外,你还需要一些技巧来提升内存和提高计算资源的利用率。一个重要的规则就是:避免采用隐式拷贝,而是采用就地操作的方式。举个例子,如果我想让一个数值x是原来的两倍,可以直接写成x*=2,而不要写成y=x*2。

    这样速度能快到2倍甚至更多。

    既然NumPy这么厉害,你该从哪儿入手学习呢?在NumPy里有两个重要的对象:ndarray(N-dimensional array object)解决了多维数组问题,而ufunc(universal function object)则是解决对数组进行处理的函数。下面,我就带你一一来看。

    ndarray对象

    ndarray实际上是多维数组的含义。在NumPy数组中,维数称为秩(rank),一维数组的秩为1,二维数组的秩为2,以此类推。在NumPy中,每一个线性的数组称为一个轴(axes),其实秩就是描述轴的数量。

    下面,你来看ndarray对象是如何创建数组的,又是如何处理结构数组的呢?

    创建数组

    import numpy as np
    a = np.array([1, 2, 3])
    b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    b[1,1]=10
    print a.shape
    print b.shape
    print a.dtype
    print b
    

    运行结果:

    (3L,)
    (3L, 3L)
    int32
    [[ 1  2  3]
     [ 4 10  6]
     [ 7  8  9]]
    

    创建数组前,你需要引用NumPy库,可以直接通过array函数创建数组,如果是多重数组,比如示例里的b,那么该怎么做呢?你可以先把一个数组作为一个元素,然后嵌套起来,比如示例b中的[1,2,3]就是一个元素,然后[4,5,6][7,8,9]也是作为元素,然后把三个元素再放到[]数组里,赋值给变量b。

    当然数组也是有属性的,比如你可以通过函数shape属性获得数组的大小,通过dtype获得元素的属性。如果你想对数组里的数值进行修改的话,直接赋值即可,注意下标是从0开始计的,所以如果你想对b数组,九宫格里的中间元素进行修改的话,下标应该是[1,1]。

    结构数组

    如果你想统计一个班级里面学生的姓名、年龄,以及语文、英语、数学成绩该怎么办?当然你可以用数组的下标来代表不同的字段,比如下标为0的是姓名、小标为1的是年龄等,但是这样不显性。

    实际上在C语言里,可以定义结构数组,也就是通过struct定义结构类型,结构中的字段占据连续的内存空间,每个结构体占用的内存大小都相同,那在NumPy中是怎样操作的呢?

    import numpy as np
    persontype = np.dtype({
        'names':['name', 'age', 'chinese', 'math', 'english'],
        'formats':['S32','i', 'i', 'i', 'f']})
    peoples = np.array([("ZhangFei",32,75,100, 90),("GuanYu",24,85,96,88.5),
           ("ZhaoYun",28,85,92,96.5),("HuangZhong",29,65,85,100)],
        dtype=persontype)
    ages = peoples[:]['age']
    chineses = peoples[:]['chinese']
    maths = peoples[:]['math']
    englishs = peoples[:]['english']
    print np.mean(ages)
    print np.mean(chineses)
    print np.mean(maths)
    print np.mean(englishs)
    

    运行结果:

    28.25
    77.5
    93.25
    93.75
    

    你看下这个例子,首先在NumPy中是用dtype定义的结构类型,然后在定义数组的时候,用array中指定了结构数组的类型dtype=persontype,这样你就可以自由地使用自定义的persontype了。比如想知道每个人的语文成绩,就可以用chineses = peoples[:][‘chinese’],当然NumPy中还有一些自带的数学运算,比如计算平均值使用np.mean。

    ufunc运算

    ufunc是universal function的缩写,是不是听起来就感觉功能非常强大?确如其名,它能对数组中每个元素进行函数操作。NumPy中很多ufunc函数计算速度非常快,因为都是采用C语言实现的。

    连续数组的创建

    NumPy可以很方便地创建连续数组,比如我使用arange或linspace函数进行创建:

    x1 = np.arange(1,11,2)
    x2 = np.linspace(1,9,5)
    

    np.arange和np.linspace起到的作用是一样的,都是创建等差数组。这两个数组的结果x1,x2都是[1 3 5 7 9]。结果相同,但是你能看出来创建的方式是不同的。

    arange()类似内置函数range(),通过指定初始值、终值、步长来创建等差数列的一维数组,默认是不包括终值的。

    linspace是linear space的缩写,代表线性等分向量的含义。linspace()通过指定初始值、终值、元素个数来创建等差数列的一维数组,默认是包括终值的。

    算数运算

    通过NumPy可以自由地创建等差数组,同时也可以进行加、减、乘、除、求n次方和取余数。

    x1 = np.arange(1,11,2)
    x2 = np.linspace(1,9,5)
    print np.add(x1, x2)
    print np.subtract(x1, x2)
    print np.multiply(x1, x2)
    print np.divide(x1, x2)
    print np.power(x1, x2)
    print np.remainder(x1, x2)
    

    运行结果:

    [ 2.  6. 10. 14. 18.]
    [0. 0. 0. 0. 0.]
    [ 1.  9. 25. 49. 81.]
    [1. 1. 1. 1. 1.]
    [1.00000000e+00 2.70000000e+01 3.12500000e+03 8.23543000e+05
     3.87420489e+08]
    [0. 0. 0. 0. 0.]
    

    我还以x1, x2数组为例,求这两个数组之间的加、减、乘、除、求n次方和取余数。在n次方中,x2数组中的元素实际上是次方的次数,x1数组的元素为基数。

    在取余函数里,你既可以用np.remainder(x1, x2),也可以用np.mod(x1, x2),结果是一样的。

    统计函数

    如果你想要对一堆数据有更清晰的认识,就需要对这些数据进行描述性的统计分析,比如了解这些数据中的最大值、最小值、平均值,是否符合正态分布,方差、标准差多少等等。它们可以让你更清楚地对这组数据有认知。

    下面我来介绍下在NumPy中如何使用这些统计函数。

    计数组/矩阵中的最大值函数amax(),最小值函数amin()

    import numpy as np
    a = np.array([[1,2,3], [4,5,6], [7,8,9]])
    print np.amin(a)
    print np.amin(a,0)
    print np.amin(a,1)
    print np.amax(a)
    print np.amax(a,0)
    print np.amax(a,1)
    

    运行结果:

    1
    [1 2 3]
    [1 4 7]
    9
    [7 8 9]
    [3 6 9]
    

    amin() 用于计算数组中的元素沿指定轴的最小值。对于一个二维数组a,amin(a)指的是数组中全部元素的最小值,amin(a,0)是延着axis=0轴的最小值,axis=0轴是把元素看成了[1,2,3], [4,5,6], [7,8,9]三个元素,所以最小值为[1,2,3],amin(a,1)是延着axis=1轴的最小值,axis=1轴是把元素看成了[1,4,7], [2,5,8], [3,6,9]三个元素,所以最小值为[1,4,7]。同理amax()是计算数组中元素沿指定轴的最大值。

    统计最大值与最小值之差 ptp()

    a = np.array([[1,2,3], [4,5,6], [7,8,9]])
    print np.ptp(a)
    print np.ptp(a,0)
    print np.ptp(a,1)
    

    运行结果:

    8
    [6 6 6]
    [2 2 2]
    

    对于相同的数组a,np.ptp(a)可以统计数组中最大值与最小值的差,即9-1=8。同样ptp(a,0)统计的是沿着axis=0轴的最大值与最小值之差,即7-1=6(当然8-2=6,9-3=6,第三行减去第一行的ptp差均为6),ptp(a,1)统计的是沿着axis=1轴的最大值与最小值之差,即3-1=2(当然6-4=2, 9-7=2,即第三列与第一列的ptp差均为2)。

    统计数组的百分位数 percentile()

    a = np.array([[1,2,3], [4,5,6], [7,8,9]])
    print np.percentile(a, 50)
    print np.percentile(a, 50, axis=0)
    print np.percentile(a, 50, axis=1)
    

    运行结果:

    5.0
    [4. 5. 6.]
    [2. 5. 8.]
    

    同样,percentile()代表着第 p 个百分位数,这里p的取值范围是0-100,如果p=0,那么就是求最小值,如果p=50就是求平均值,如果p=100就是求最大值。同样你也可以求得在axis=0 和 axis=1两个轴上的p%的百分位数。

    统计数组中的中位数median()、平均数mean()

    a = np.array([[1,2,3], [4,5,6], [7,8,9]])
    #求中位数
    print np.median(a)
    print np.median(a, axis=0)
    print np.median(a, axis=1)
    #求平均数
    print np.mean(a)
    print np.mean(a, axis=0)
    print np.mean(a, axis=1)
    

    运行结果:

    5.0
    [4. 5. 6.]
    [2. 5. 8.]
    5.0
    [4. 5. 6.]
    [2. 5. 8.]
    

    你可以用median()和mean()求数组的中位数、平均值,同样也可以求得在axis=0和1两个轴上的中位数、平均值。你可以自己练习下看看运行结果。

    统计数组中的加权平均值average()

    a = np.array([1,2,3,4])
    wts = np.array([1,2,3,4])
    print np.average(a)
    print np.average(a,weights=wts)
    

    运行结果:

    2.5
    3.0
    

    average()函数可以求加权平均,加权平均的意思就是每个元素可以设置个权重,默认情况下每个元素的权重是相同的,所以np.average(a)=(1+2+3+4)/4=2.5,你也可以指定权重数组wts=[1,2,3,4],这样加权平均np.average(a,weights=wts)=(1*1+2*2+3*3+4*4)/(1+2+3+4)=3.0。

    统计数组中的标准差std()、方差var()

    a = np.array([1,2,3,4])
    print np.std(a)
    print np.var(a)
    

    运行结果:

    1.118033988749895
    1.25
    

    方差的计算是指每个数值与平均值之差的平方求和的平均值,即mean((x - x.mean())** 2)。标准差是方差的算术平方根。在数学意义上,代表的是一组数据离平均值的分散程度。所以np.var(a)=1.25, np.std(a)=1.118033988749895。

    NumPy排序

    排序是算法中使用频率最高的一种,也是在数据分析工作中常用的方法,计算机专业的同学会在大学期间的算法课中学习。

    那么这些排序算法在NumPy中实现起来其实非常简单,一条语句就可以搞定。这里你可以使用sort函数,sort(a, axis=-1, kind=‘quicksort’, order=None),默认情况下使用的是快速排序;在kind里,可以指定quicksort、mergesort、heapsort分别表示快速排序、合并排序、堆排序。同样axis默认是-1,即沿着数组的最后一个轴进行排序,也可以取不同的axis轴,或者axis=None代表采用扁平化的方式作为一个向量进行排序。另外order字段,对于结构化的数组可以指定按照某个字段进行排序。

    a = np.array([[4,3,2],[2,4,1]])
    print np.sort(a)
    print np.sort(a, axis=None)
    print np.sort(a, axis=0)  
    print np.sort(a, axis=1)  
    

    运行结果:

    [[2 3 4]
     [1 2 4]]
    [1 2 2 3 4 4]
    [[2 3 1]
     [4 4 2]]
    [[2 3 4]
     [1 2 4]]
    

    你可以自己计算下这个运行结果,然后再跑一遍比对下。

    总结

    在NumPy学习中,你重点要掌握的就是对数组的使用,因为这是NumPy和标准Python最大的区别。在NumPy中重新对数组进行了定义,同时提供了算术和统计运算,你也可以使用NumPy自带的排序功能,一句话就搞定各种排序算法。

    当然要理解NumPy提供的数据结构为什么比Python自身的“更高级、更高效”,要从对数据指针的引用角度进行理解。

    展开全文
  • PythonNumpy详细教程

    万次阅读 多人点赞 2018-03-16 13:59:14
    NumPy 是一个 Python 包。 它代表 “Numeric Python”。 它是一个由多维数组对象和用于处理数组的例程集合组成的库。 Numeric,即 NumPy 的前身,是由 Jim Hugunin 开发的。 也开发了另一个包 Numarray ,它拥有...
  • 70个NumPy练习:在Python下一举搞定机器学习矩阵运算 翻译| 王柯凝责编 | suisui【导读】Numpy是一个开源的Python科学计算库,专用于存储和处理大型矩阵,相比Python自身的嵌套列表结构要高效很多,是数据分析、统计...
  • python numpy学习查找最近值

    千次阅读 2018-06-08 11:18:42
    找出数组与给定值最接近的数(通用方法)。(例:任一数组Z=array([[0,1,2,3],[4,5,6,7]]),给任一定值z=5.1)import numpy as npZ=np.array([[0,1,2,3],[4,5,6,7]])print(Z)x=5.1a=abs(Z-x)print(a)b=a.min()...
  • 今天小编就为大家分享一篇python numpy元素的区间查找方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 图书推荐:《Python数据分析、挖掘与可视化》(慕课版)(ISBN:978-7-115-52361-7),董付国,人民邮电出版社,定价49.8元,京东、当当、天猫均有销售。图书封面:京...
  • 本篇文章给大家带来的内容是关于python中Numpy和Pandas模块的详细介绍(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。本章学习两个科学运算当中最为重要的两个模块,一个是 numpy,一个...
  • NumPy更加高效 NumPy数组结构比Python本身的list更加的节省资源: 列表 list 的元素在系统内存是分散存储的,而 NumPy 数组存储在一个均匀连续的内存块。...因为数据连续的存储在内存NumPy 直接...
  • 我已经在线安装了numpy二进制文件,但是当我尝试在我的脚本运行"import numpy"然后运行一些numpy命令时,但python shell返回错误说1234Traceback (most recent call last):File"/Users/Admin/Desktop/NumpyTest....
  • 本篇博客所有示例使用Jupyter NoteBook演示。 Python数据分析系列笔记基于:利用Python进行数据分析(第2版)  ...NumPy数组可以让你将许多中数据处理任务表述为简洁的数组表达式(不需要写循环).用数组表达式代替循环...
  • matlab代码替换python numpyNumPyPython编程语言的库.NumPy基本上是数字Python。 它增加了对大型多维数组...在NumPy数组中查找元素。 数学(MATLAB替代)绘图(Matplotlib)后端(熊猫,摄影)机器学习 SANJANA RK
  • python中list中得元素可以是任意值,python中list元素在系统内是分散存储得,而Numpy数组存储在一个均匀连续得内存块中,数组计算遍历所有的额元素,而list还需要对内存地址进行查找,可以节省计算资源, ...
  • Python中Numpy

    2021-02-23 22:06:16
    NumPy是一个高性能的科学计算和数据分析基础包,在数据分析领域有很多应用; 具有多维数组对象、线性代数、傅里叶变换和随机数等强大功能; 一、Numpy的安装 在平时的使用,我们习惯将“import numpy”写成...
  • 04丨Python科学计算:用NumPy快速处理数据 为什么要用 NumPy 数组结构而不是 Python 本身的列表 list? 因为列表 list 的元素在系统内存是分散存储的,而 NumPy 数组存储在一个均匀连续的内存块。这样数组计算...
  • Python数据处理之Numpy

    2018-04-02 15:45:57
    NumPy系统是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多(该结构也可以用来表示矩阵(matrix))。 如何安装Numpy? 博主...
  • python numpyNumPy (pronounced "numb pie") is one of the most important packages to grasp when you’re starting to learn Python. NumPy(读作“麻木派”)是您开始学习Python时要掌握的最重要的软件包之一。 ...
  • 目录 缺失值处理 重复值处理 缺失值处理 第一步:判断是否有缺失值,将缺失值找...在numpy中缺失值用np.nan表示 第二步:对缺失值进行填充 数组[np.isnan(数组)]=填充值 重复值处理 使用np.unique(数组) ...
  • Python Numpy高效数据处理(一)——获取数组B中每个元素在数组A中的索引值Python Numpy高效数据处理(一)获取数组B中每个元素在数组A中的索引值...做算法的,在工作中经常需要处理大量的数据python中的for循环...
  • Python numpy数据结构 学习笔记

    千次阅读 2018-05-31 11:34:56
    一、概念介绍numpyPython的一个...对于数据的运算,用矩阵会比python自带的字典或者列表快好多主要应用有:数据分析机器学习深度学习二、安装请看: MAC/Windows/Linux环境numpy和pandas安装三、numpy基本属性...
  • 使用NumPy读取MNIST数据

    千次阅读 2019-11-19 17:04:15
    NumPyPython 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。主页为https://numpy.org/。 安装NumPy 使用pip工具来安装。 python -m pip install numpy ...
  • Python Numpy 教程

    2019-07-28 09:56:58
    Numpy的意思是numeric python,它是一个用于计算、处理多维数组的python包,在人工智能/深度学习项目得到广泛应用。 对象 本教程面向初学者或专业人士。 预备知识 熟悉Python编程。Python编程可参考我们的...
  • 比如保存在关系型数据库或以制表符/逗号为分隔符的文本文件的那些数据。 多维数组(矩阵) 通过关键列(对于SQL用户来说,就是主键和外键)相互联系的多个表 间隔平均或不平均的时间序列。 Numpy介绍 Numpy是...
  • numpy查找适合任意数据的椭圆体,对其进行绘制或写入文件。 (应该同时适用于python 2.7和python 3) 用于3轴磁力计校准。 如果您想使椭圆适合任意数据,请查看问题#11-我试图解释如何做到这一点。 还要浏览其他未...
  • python numpy元素的区间查找

    万次阅读 2017-12-12 15:58:52
    找了半天,以为numpy的where函数像matlab 的find函数一样好用,能够返回一个区间内的元素索引位置。结果没有。。(也可能是我没找到) 故自己写一个函数,找多维数组下的,在某个区间的元素位置 import numpy as ...
  • python list 和numpy查找速度对比

    千次阅读 2019-07-13 14:56:44
    list存储百万数据查找的时候很慢,之前听说numpy优化的很好,支持多核并行,对比了一下。 简单查询的时候list比numpy的array的速度稍微快点(仅限于我自己的任务) a = [[i,i,i,[i,i]] for i in range(100000)] ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,770
精华内容 6,308
关键字:

numpy中查找数据python

python 订阅