这部分是NumPy数组的快速概述,演示了 n 维 (n>=2) 数组是如何表示和操作的,介绍了如何将常用函数应用于 n 维数组(不使用 for 循环),以及n 维数组的轴和形状属性。
NumPy的主要对象是同构多维数组。它是一个元素(通常是数字)表,所有元素(通常是数字)都具有相同的类型,由非负整数元组索引。在NumPy中,维度称为轴。
数组对象的基本属性:
属性 | 解释 |
---|---|
ndarray.ndim | 数组的轴数(维数) |
ndarray.shape | 数组的尺寸。返回一个整数元组,元组的长度是轴数,元组中的元素指示每个维度中数组的大小。 |
ndarray.size | 数组的元素总数。这等于shape元组中所有元素的乘积。 |
ndarray.dtype | 描述数组中元素类型的对象。可以使用标准Python类型创建或指定dtype。此外,NumPy还提供了自己的类型,如numpy.int32、numpy.int16 、numpy.float64 |
ndarray.itemsize | 数组中每个元素的大小(以字节为单位) |
ndarray.data | 包含数组实际元素的缓冲区。通常,我们不需要使用此属性,因为我们将使用索引工具访问数组中的元素。 |
a=np.arange(15).reshape(3,5) print(a) print(type(a)) print(a.ndim) print(a.shape) print(a.size) print(a.dtype.name) print(a.itemsize)
[[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14]] # a <class 'numpy.ndarray'> # type(a) 2 # a.ndim 维数 (3, 5) # a.shape 15 # a.size 3*5=15 int32 # a.dtype 4 # a.itemsize
1. 从常规Python列表或元组出发创建数组
a=np.array([1,2,3,4,5],dtype=float) # 列表转换为一维数组 b=np.array([(1,2,3,4),(5,6,7,8)]) # 元组的列表转换为二维数组 c=np.array([[( 1, 2, 3, 4),( 5, 6, 7, 8)], [( 9,10,11,12),(13,14,15,16)], [(17,18,19,20),(21,22,23,24)]])
[1. 2. 3. 4. 5.] ------- a [[1 2 3 4] [5 6 7 8]] ------- b [[[ 1 2 3 4] [ 5 6 7 8]] [[ 9 10 11 12] [13 14 15 16]] [[17 18 19 20] [21 22 23 24]]] ------- c
2. 创建具有初始占位符内容的数组
通常,最初数组的元素是未知的,但其大小是已知的。因此,NumPy提供了几个函数来创建具有初始占位符内容的数组,这最大限度地减少了数组动态增长的必要性。
a=np.zeros((2,3)) # 创建一个充满0的数组,参数是表明数组形状的元组 b=np.ones((2,3)) # 创建一个充满1的数组,参数是表明数组形状的元组 c=np.empty((2,3,4)) # 创建一个数组,其初始内容是随机的
[[0. 0. 0.] [0. 0. 0.]] [[1. 1. 1.] [1. 1. 1.]] [[[1.06018346e-311 8.26448246e-315 8.26448183e-315 8.26448198e-315] [1.06018346e-311 1.06018346e-311 8.26448752e-315 1.06018346e-311] [8.26448325e-315 1.06018346e-311 8.26448183e-315 1.06018346e-311]] [[8.26448752e-315 1.06018346e-311 8.26448198e-315 1.06018346e-311] [8.26448183e-315 8.26448183e-315 1.06018346e-311 8.26448214e-315] [1.06018346e-311 8.26448183e-315 1.06018346e-311 8.26449953e-315]]]
3. 创建数字序列
np.arange(x,y,z):创建一个
[
x
,
y
)
[x,y)
[x,y) 内以z为步长的数组
np.linspace(x,y,z):创建一个
[
x
,
y
]
[x,y]
[x,y] 内步长相同有z个值的数组(平均分成z-1份)
a=np.arange(10,30,5) b=np.arange(0,2,0.3) c=np.linspace(0,2,9) x = np.linspace(0, 2 * math.pi, 10) #在0~2π之间取10个点 y = np.sin(x) #用以绘制y=sin(x)函数图
[10 15 20 25] # a -步长为5,包括10,不包括30 [0. 0.3 0.6 0.9 1.2 1.5 1.8] # b [0. 0.25 0.5 0.75 1. 1.25 1.5 1.75 2. ] # c
绘制出x-y关系图,可以看到当点取得够多,就可以绘制出非常平滑的图,因此np.linspace经常被用来生成序列绘制函数图像。
打印数组时,NumPy 以类似于嵌套列表的方式显示它,但具有以下布局:
然后将一维数组打印为行,将二维数组打印为矩阵,将三维数组打印为矩阵列表。
我尝试了一个四维数组:a=np.arange(120).reshape((2,3,4,5))
[[[[ 0 1 2 3 4] [ 5 6 7 8 9] [ 10 11 12 13 14] [ 15 16 17 18 19]] [[ 20 21 22 23 24] [ 25 26 27 28 29] [ 30 31 32 33 34] [ 35 36 37 38 39]] [[ 40 41 42 43 44] [ 45 46 47 48 49] [ 50 51 52 53 54] [ 55 56 57 58 59]]] [[[ 60 61 62 63 64] [ 65 66 67 68 69] [ 70 71 72 73 74] [ 75 76 77 78 79]] [[ 80 81 82 83 84] [ 85 86 87 88 89] [ 90 91 92 93 94] [ 95 96 97 98 99]] [[100 101 102 103 104] [105 106 107 108 109] [110 111 112 113 114] [115 116 117 118 119]]]]
对于 n p . a r a n g e ( X ) . r e s h a p e ( ( x 1 , x 2 , . . . , x n − 1 , x n ) ) np.arange(X).reshape\big((x_1,x_2,...,x_{n-1},x_n)\big) np.arange(X).reshape((x1,x2,...,xn−1,xn)),满足:
.
如果数组太大而无法打印,NumPy 会自动跳过数组的中心部分,只打印角,要禁用此行为并强制 NumPy 打印整个数组,可以使用 np.set_printoptions(threshold=sys.maxsize)
1.数组上的算术运算符将逐个计算对应元素 ,并创建一个新数组进行结果填充
注意区别对应元素相乘与矩阵相乘,前者a*b 或np.multiply,后者用a@b或a.dot(b)
a=np.array([(10,20),(30,40)]) b=np.array([(1,2),(3,4)]) print(a-b) print(a**2) print(a<25) print(a*b) print(np.multiply(a,b)) print(a@b) print(a.dot(b))
[[ 9 18] [27 36]] # a-b [[ 100 400] [ 900 1600]] # a^2 [[ True True] [False False]] # a>25 [[ 10 40] [ 90 160]] # a*b [[ 10 40] [ 90 160]] # np.multiply(a,b) [[ 70 100] [150 220]] # a@b [[ 70 100] [150 220]] # a.dot(b)
2.某些操作(如 +=)会就地修改现有数组,而不是创建新数组
3.当处理不同类型的数组时,生成的数组的类型对应于更通用或更精确的数组类型(这种行为称为 upcasting)
4.许多一元运算(如计算数组中所有元素的总和)都是作为类的方法实现的,作用于整个数组,就好像它是一个数字列表一样,无论其形状如何。通过axis参数也可以沿数组的指定轴应用操作
a=np.array([(10,20),(30,40)]) print(a.sum()) # 求所有元素和 100 print(a.max()) # 求所有元素中的最大值 40 print(a.min()) # 求所有元素中的最小值 10
a=np.array([(10,20),(30,40)]) print(a.sum(axis=0)) # 每一列元素和 [40 60] print(a.max(axis=0)) # 每一列最大值 [30 40] print(a.min(axis=1)) # 每一行最小值 [10 30]
这里列举了一些常用的函数,它们大部分都有着较为丰富的扩展功能以满足各种需求,比如很多计算可以针对整个数组,也可以针对某一个轴进行,且有的操作会改变原数组,而有的操作不改变,这里先不详述,只表达一种最简单的使用情况。
函数 | 解释 |
---|---|
np.exp(A) | 计算指数 |
np.sqrt(A) | 计算平方根 |
np.add(A,B) | 计算数组A,B对应元素相加,即A+B |
np.average(A) | 计算平均值,可以计算加权平均值 |
np.mean(A) | 计算平均值,无法计算加权平均 |
np.maximum(A,B) | 取对应位置较大的元素形成新的数组 |
np.minimum(A,B) | 取对应位置较小的元素形成新的数组 |
np.median(A) | 计算所有元素的中位数 |
np.prod(A) | 计算所有元素相乘的结果 |
np.sort(A) | 返回一个排序后的副本,A本身不变 |
np.std(A) | 计算标准差 |
np.var(A) | 计算方差 |
以为数组的索引、切片、迭代和标准Python序列(如列表)类似。而对于多维的数组:
这里打算另外写一篇详细探讨