一.数组变维
1.1 reshape
reshape()
可以改变数组维度,但是返回的是一个新的数组,原数组的形状不会被修改。reshape后产生的新数组是原数组的一个视图,即它与原数组共享相同的数据,但可以有不同的形状或维度,且对视图的修改会直接影响原数组数据。
元素总数必须匹配:新形状中的元素总数必须与原数组中的元素总数相同,即(2,3)可以改成(3,2)而不能是(2,2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import numpy as np a = np.array([[1,2,3],[4,5,6]])
b = a.reshape(3,2) print(a)
print() print(b)
|
结果:
1 2 3 4 5 6
| [[1 2 3] [4 5 6]]
[[1 2] [3 4] [5 6]]
|
1 2 3 4 5 6 7 8 9 10 11
| import numpy as np a = np.array([1,2,3,4,5,6,7,8,9,10,11,12]) b = a.reshape(2,2,3) print(a) print() print(b)
|
结果:
1 2 3 4 5 6 7
| [ 1 2 3 4 5 6 7 8 9 10 11 12]
[[[ 1 2 3] [ 4 5 6]]
[[ 7 8 9] [10 11 12]]]
|
事实确实证明,只要两个形状里元素个数一致,形状怎么变,或者改变维度也可以。
-1 作为占位符:
你可以使用-1
作为占位符,让 numpy 自动计算某个维度的大小。也就是-1
在哪,就会自动改变那个行或列的大小以适配新的形状。
1 2 3 4 5 6
| import numpy as np a = np.array([[1,2,3],[4,5,6]]) b = a.reshape(3,-1) print(b)
|
结果:
1.2 flat
返回一个一维迭代器,用于遍历数组中的所有元素。
1 2 3 4 5 6 7 8
| import numpy as np a = np.array([[1,2,3],[4,5,6]])
b = a.flat for i in b: print(i)
|
结果:
1.3 flatten()
用于将多维数组转换为一维数组,返回的也是一个副本
ndarray.flatten(order='C')
1 2 3 4 5 6
| import numpy as np a = np.array([[1,2,3],[4,5,6]]) b = a.flatten() print(b)
|
结果:
1.4 ravel()
ndarray.ravel()
其用于将多维数组转换为一维数组。与 flatten() 不同,ravel() 返回的是原数组的一个视图(view),而不是副本。因此,对返回的数组进行修改会影响原数组数据。
1 2 3 4 5 6 7 8 9
| import numpy as np a = np.array([[1,2,3],[4,5,6]]) b = a.ravel() print(b) b[0] = 100 print(a)
|
结果:
1 2 3
| [1 2 3 4 5 6] [[100 2 3] [ 4 5 6]]
|
二.数组转置
| transpose | 将数组的维度值进行对换,比如二维数组维度(2,4)使用该方法后为(4,2) |
| ndarray.T | 与 transpose 方法相同 |
1 2 3 4 5 6 7 8 9 10 11 12 13
| import numpy as np
a = np.arange(1,7).reshape(2,3) print(a) print() print(a.T) print()
print(np.transpose(a))
|
结果:
1 2 3 4 5 6 7 8 9 10
| [[1 2 3] [4 5 6]]
[[1 4] [2 5] [3 6]]
[[1 4] [2 5] [3 6]]
|
如果是2维以上的数组怎么转置呢?来看看:
1 2 3 4 5 6 7 8 9 10 11 12 13
| import numpy as np x = np.array([1,2,3,4,5,6,7,8])
x.shape = (4,2,1,1) print(x.shape) print()
b = np.transpose(x) print(b.shape)
|
结果:
1 2 3
| (4, 2, 1, 1)
(1, 1, 2, 4)
|
可见就是把原来的形状反向输出。
三.升维和降维
多维数组(也称为 ndarray)的维度(或轴)是从外向内编号的。这意味着最外层的维度是轴0,然后是轴1,依此类推。
比如[ [ [ 1,2,3 ] ] ]
,最外面那层括号就是轴0,也就是最外层维度,该形状为(1,1,3)。维度长度分别为1,1,3。
| expand_dims(arr, axis) | arr:输入数组、axis:新轴插入的位置 | 在指定位置插入新的轴(相对于结果数组而言),从而扩展数组的维度 |
| squeeze(arr, axis) | axis:取值为整数或整数元组,用于指定需要删除的维度所在轴,指定的维度值必须为 1 ,否则将会报错,若为 None,则删除数组维度中所有为 1 的项 |删除数组中维度为 1 的项 |
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
| import numpy as np
a = np.array([1, 2, 3]) print(a.shape)
b = np.expand_dims(a, axis=0) print(b.shape) print(b)
print()
c = np.expand_dims(a, axis=1) print(c.shape) print(c)
print()
d = np.expand_dims(c, axis=1) print(d.shape) print(d)
|
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| (3,) (1, 3) [[1 2 3]]
(3, 1) [[1] [2] [3]]
(3, 1, 1) [[[1]]
[[2]]
[[3]]]
|
你可以这样理解,按轴0升维是在最外层加上俩括号,按最大轴升维是在最内层元素两旁加上俩括号。
1 2 3 4 5 6 7
| import numpy as np
a = np.array([[[1, 2, 3]]])
b = np.squeeze(a, axis = 0) print(b)
|
结果:
1 2 3 4 5 6 7
| a = np.array([1, 2, 3]) a.shape = (3, 1) print(a) np.squeeze(a,axis=0)
|
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| [[1] [2] [3]]
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[31], line 7 4 a.shape = (3, 1) 5 print(a) ----> 7 np.squeeze(a,axis=0)
File c:\Users\Clocky7\anaconda3\envs\pyhon-numpy\lib\site-packages\numpy\core\fromnumeric.py:1558, in squeeze(a, axis) 1556 return squeeze() 1557 else: -> 1558 return squeeze(axis=axis)
ValueError: cannot select an axis to squeeze out which has size not equal to one
|
四.连接数组
| hstack(tup) | tup:可以是元组,列表,或者numpy数组返回结果为numpy的数组 | 按水平顺序堆叠序列中数组(列方向) |
| vstack(tup) | tup:可以是元组,列表,或者numpy数组返回结果为numpy的数组 | 按垂直顺序堆叠序列中数组(行方向) |
其上分别要求行数一致和列数一致,而且 vstack()
和 hstack()
要求堆叠的数组在某些维度上具有相同的形状,否则无法堆叠。
1 2 3 4 5 6 7 8 9
| import numpy
a = numpy.array([1, 2, 3]) b = numpy.array([4, 5, 6]) print(np.hstack((a, b)))
print(np.vstack((a, b)))
|
结果:
1 2 3
| [1 2 3 4 5 6] [[1 2 3] [4 5 6]]
|
五.分割数组
| hsplit(ary, indices_or_sections) | ary:原数组 indices_or_sections:按列分割的索引位置 | 数组水平分割为多个子数组(按列) |
| vsplit(ary, indices_or_sections) | ary:原数组 indices_or_sections:按行分割的索引位置 | 数组垂直分割为多个子数组(按行) |
1 2 3 4 5 6
| import numpy as np a = np.array([[1, 2, 3,4], [ 5,6,7,8]])
b = np.hsplit(a,[1,3]) print(b)
|
结果:
1 2 3 4
| [array([[1], [5]]), array([[2, 3], [6, 7]]), array([[4], [8]])]
|
六.矩阵运算
6.1 np.dot
是一个通用的点积函数,适用于多种维度的数组。
1 2 3 4
| a = numpy.array([1, 2, 3]) b = numpy.array([4, 5, 6]) print(numpy.dot(a, b))
|
结果:
1 2 3 4
| a = numpy.array([[1, 2],[3, 4]]) b = numpy.array([[5, 6],[7, 8]]) print(numpy.dot(a, b))
|
结果:
注意:矩阵 用 * 相乘是逐元素(element-wise)乘法,而不是线性代数中的矩阵乘法。也就是对应元素相乘,同样需要广播机制。
6.2 np.matmul
是专门用于矩阵乘法的函数,适用于二维及更高维度的数组。np.dot
是通用点积函数,np.matmul
专门用于矩阵运算,性能要好于np.dot
。
6.3 np.linalg.det
求方阵行列式。
1 2 3 4
| import numpy as np a = np.array([[1, 2], [3, 4]]) print(np.linalg.det(a))
|
结果: