NumPy
基础1本章示例代码中的输入和输出均来自IPython会话。
NumPy
数组对象NumPy
中的ndarray
是一个多维数组对象,该对象由两部分组成:
大部分的数组操作仅仅修改修改元数据部分,而不改变底层的实际数据。
在第1章中,我们已经知道如何使用arange
函数创建数组。实际上,当时创建的数组只是包含一组数字的一维数组,而ndarray
支持更高的维度。
NumPy
数组一般是同质的
(但有一种特殊的数组类型例外,它是异质的),即数组中的所有元素类型必须是一致的。这样有一个好处:如果我们知道数组中的元素均为同一类型,该数组所需的存储空间就很容易确定下来。
与Python中一样,NumPy数组的下标也是从0开始的。数组元素的数据类型用专门的对象表示。
我们再次用arange
函数创建数组,并获取其数据类型:
In [1]: import numpy as np In [2]: a = np.arange(5) In [3]: a.dtype Out[3]: dtype('int32')
数组a的数据类型为int32(在我的机器上是这样),当然如果你使用64位的Python,得到的结果可能是int64。不论是哪种情形,该数组的数据类型都是整数(64位或32位)。
除了数据类型,数组的维度也是重要的属性。
第1章中的例子演示了怎样创建一个向量(即一维的NumPy数组)。向量在数学中很常用,但大部分情况下,我们需要更高维的对象。先来确定一下刚刚所创建向量的维度:
In [4]: a Out[4]: array([0, 1, 2, 3, 4]) In [5]: a.shape Out[5]: (5,)
正如你所看到的,这是一个包含5个元素的向量,取值分别为0~4
的整数。数组的shape
属性返回一个元组(tuple),元组中的元素即为NumPy
数组每一个维度上的大小。上面例子中的数组是一维的,因此元组中只有一个元素。
既然我们已经知道如何创建向量,现在可以试着创建多维的NumPy
数组,并查看其维度了。
(1) 创建一个多维数组。
(2) 显示该数组的维度。
In [6]: m = np.array([np.arange(2),np.arange(2)]) In [7]: m Out[7]: array([[0, 1], [0, 1]]) In [8]: m.shape Out[8]: (2, 2)
我们将arange
函数创建的数组作为列表元素,把这个列表作为参数传给array
函数,从而创建了一个2×2的数组,而且没有出现任何报错信息。
array
函数可以依据给定的对象生成数组。给定的对象应是类数组,如Python中的列表。在上面的例子中,我们传给array
函数的对象是一个NumPy
数组的列表。像这样的类数组对象是array
函数的唯一必要参数,其余的诸多参数均为有默认值的可选参数。
问题1 ndarray对象的维度属性是以下列哪种方式存储的?
(1) 逗号隔开的字符串
(2) Python列表(list)
(3) Python元组(tuple)
有时候,我们需要选取数组中的某个特定元素。首先还是创建一个2×2的多维数组:
In [9]: a = np.array([[1,2],[3,4]]) In [10]: a Out[10]: array([[1, 2], [3, 4]])
在创建这个多维数组时,我们给array
函数传递的对象是一个嵌套的列表。现在来依次选取该数组中的元素。记住,数组的下标是从0开始的。
In [11]: a[0,0] Out[11]: 1 In [12]: a[0,1] Out[12]: 2 In [13]: a[1,0] Out[13]: 3 In [14]: a[1,1] Out[14]: 4
是的,从数组中选取元素就是这么简单。对于数组a,只需要用a[m,n]选取各数组元素,其
中m和n为元素下标,对应的位置如下表所示。
NumPy
数据类型Python支持的数据类型有整型、浮点型以及复数型,但这些类型不足以满足科学计算的需求,因此NumPy
添加了很多其他的数据类型。在实际应用中,我们需要不同精度的数据类型,它们占用的内存空间也是不同的。在NumPy
中,**大部分数据类型名是以数字结尾的,这个数字表示其在内存中占用的位数。**下面的表格(整理自NumPy用户手册)列出了NumPy
中支持的数据类型。
每一种数据类型均有对应的类型转换函数:
In [15]: np.float64(42) Out[15]: 42.0 In [17]: np.int8(42.0) Out[17]: 42 In [18]: np.bool(42) C:\Users\administrator\AppData\Local\Programs\Python\Python37\Scripts\ipython:1: Deprecatio nWarning: `np.bool` is a deprecated alias for the builtin `bool`. To silence thi s warning, use `bool` by itself. Doing this will not modify any behavior and is safe. If you specifically wanted the numpy scalar type, use `np.bool_` here. Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdo cs/release/1.20.0-notes.html#deprecations Out[18]: True In [20]: np.float(True) C:\Users\administrator\AppData\Local\Programs\Python\Python37\Scripts\ipython:1: Deprecatio nWarning: `np.float` is a deprecated alias for the builtin `float`. To silence t his warning, use `float` by itself. Doing this will not modify any behavior and is safe. If you specifically wanted the numpy scalar type, use `np.float64` here . Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdo cs/release/1.20.0-notes.html#deprecations Out[20]: 1.0
注:在1.20版本中np.bool
、 np.float
都是对应系统函数的别名
在NumPy中,许多函数的参数中可以指定数据类型,通常这个参数是可选的:
In [23]: np.arange(7, dtype=np.uint16) Out[23]: array([0, 1, 2, 3, 4, 5, 6], dtype=uint16)
需要注意的是,复数是不能转换为整数的,这将触发TypeError错误:
In [24]: np.int(42.0+1.j) C:\Users\administrator\AppData\Local\Programs\Python\Python37\Scripts\ipython:1: Deprecatio nWarning: `np.int` is a deprecated alias for the builtin `int`. To silence this warning, use `int` by itself. Doing this will not modify any behavior and is saf e. When replacing `np.int`, you may wish to use e.g. `np.int64` or `np.int32` to specify the precision. If you wish to review your current use, check the releas e note link for additional information. Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdo cs/release/1.20.0-notes.html#deprecations --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-24-4b5b3467cc1e> in <module> ----> 1 np.int(42.0+1.j) TypeError: can't convert complex to int
同样,复数也不能转换为浮点数。不过,浮点数却可以转换为复数,例如complex(1.0)
。注意,有j
的部分为复数的虚部。
数据类型对象是numpy.dtype
类的实例。如前所述,NumPy
数组是有数据类型的,更确切地说,NumPy
数组中的每一个元素均为相同的数据类型。数据类型对象可以给出单个数组元素在内存中占用的字节数,即dtype
类的itemsize
属性:
In [25]: a.dtype.itemsize Out[25]: 4
NumPy
可以使用字符编码来表示数据类型,这是为了兼容NumPy
的前身Numeric
。我不推荐使用字符编码,但有时会用到,因此下面还是列出了字符编码的对应表。读者应该优先使用dtype
对象来表示数据类型,而不是这些字符编码。
下面的代码创建了一个单精度浮点数数组:
In [26]: np.arange(7, dtype='f') Out[26]: array([0., 1., 2., 3., 4., 5., 6.], dtype=float32)
与此类似,还可以创建一个复数数组:
In [28]: np.arange(7, dtype='D') Out[28]: array([0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j, 4.+0.j, 5.+0.j, 6.+0.j])