Numpy知识总结
基础知识
轴的概念
NumPy的主要对象是同构多维数组。它是一个元素表(通常是数字),所有类型都相同,由非负整数元组索引。在NumPy维度中称为 轴 。
例如,3D空间中的点的坐标[1, 2, 1]具有一个轴。该轴有3个元素,所以我们说它的长度为3.在下图所示的例子中,数组有2个轴。第一轴的长度为2,第二轴的长度为3。
[[ 1., 0., 0.],
[ 0., 1., 2.]]
Numpy的属性
ndarray.ndim - 数组的轴(维度)的个数。在Python世界中,维度的数量被称为rank。
ndarray.shape - 数组的维度。这是一个整数的元组,表示每个维度中数组的大小。对于有 n 行和 m 列的矩阵,shape 将是 (n,m)。因此,shape 元组的长度就是rank或维度的个数 ndim。
ndarray.size - 数组元素的总数。这等于 shape 的元素的乘积。
ndarray.dtype - 一个描述数组中元素类型的对象。可以使用标准的Python类型创建或指定dtype。另外NumPy提供它自己的类型。例如numpy.int32、numpy.int16和numpy.float64。
ndarray.itemsize - 数组中每个元素的字节大小。例如,元素为 float64 类型的数组的 itemsize 为8(=64/8),而 complex32 类型的数组的 itemsize 为4(=32/8)。它等于 ndarray.dtype.itemsize 。
ndarray.data - 该缓冲区包含数组的实际元素。通常,我们不需要使用此属性,因为我们将使用索引访问数组中的元素。
一个例子
>>> import numpy as np
>>> array=np.array([[1,2,3],[2,3,4]])
>>> print(array)
[[1 2 3]
[2 3 4]]
>>> print('number of dim:',array.ndim)
number of dim: 2
>>> print('shape:',array.shape)
shape: (2, 3)
>>> print('size:',array.size)
size: 6
>>> print('dtype:',array.dtype)
dtype: int32
>>> print('itemsize:',array.itemsize)
itemsize: 4
>>> print('data:',array.data)
data: <memory at 0x0D796DC8>
>>>
数组创建
使用array函数从常规Python列表或元组中创建数组。得到的数组的类型是从Python列表中元素的类型推导出来的。
>>> import numpy as np
>>> a=np.array([[1,2,3],[4,5,6]])
>>> print(a)
[[1 2 3]
[4 5 6]]
>>> b=np.array([(1,2,3),(4,5,6)])
>>> print(b) //array 还可以将序列的序列转换成二维数组,将序列的序列的序列转换成三维数组,等等。
[[1 2 3]
[4 5 6]]
>>> c=np.array([[1,2],[3,4]],dtype=complex) //可以在创建时显式指定数组的类型
>>> print(c)
[[1.+0.j 2.+0.j]
[3.+0.j 4.+0.j]]
函数zeros创建一个由0组成的数组
函数 ones创建一个完整的数组
函数empty 创建一个数组,其初始内容是随机的,取决于内存的状态。默认情况下,创建的数组的dtype是 float64 类型的
为了创建数字组成的数组,NumPy提供了一个类似于range的函数,该函数返回数组而不是列表。
>>> import numpy as np
>>> a=np.ones((3,4),dtype=np.int16)
>>> print(a)
[[1 1 1 1]
[1 1 1 1]
[1 1 1 1]]
>>> a=np.empty((3,4))
>>> print(a)
[[2.87943118e-316 0.00000000e+000 6.32639033e-292 2.87945134e-316]
[0.00000000e+000 0.00000000e+000 0.00000000e+000 2.87932684e-316]
[0.00000000e+000 6.32794997e-292 0.00000000e+000 0.00000000e+000]]
>>> a=np.zeros((3,4))
>>> print(a)
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
>>> a=np.arange(10,20,2) //起始位置,结束位置,步长
>>> print(a)
[10 12 14 16 18]
>>> a=np.arange(12).reshape((3,4)) //重新定义长和宽
>>> print(a)
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
>>> a=np.linspace(1,10,20) //生成线段,数列,也可更改reshape
>>> print(a)
[ 1. 1.47368421 1.94736842 2.42105263 2.89473684 3.36842105
3.84210526 4.31578947 4.78947368 5.26315789 5.73684211 6.21052632
6.68421053 7.15789474 7.63157895 8.10526316 8.57894737 9.05263158
9.52631579 10. ]
#reshape的更多用法
>>> c = np.arange(24).reshape(2,3,4) # 3d array
>>> print(c)
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
基本操作
数组上的算术运算符会应用到 元素 级别。包括加,减,平方,取正余弦(调用numpy.sin(a)函数…
>>> import numpy as np
>>> a=np.array([10,20,30,40])
>>> b=np.arange(4)
>>> print(a,b)
[10 20 30 40] [0 1 2 3]
>>> c=a+b
>>> print(c)
[10 21 32 43]
>>> c=a-b
>>> print(c)
[10 19 28 37]
>>> c=b**2
>>> print(c)
[0 1 4 9]
>>> c=10*np.sin(a)
>>> print(c)
[-5.44021111 9.12945251 -9.88031624 7.4511316 ]
>>> print(b)
[0 1 2 3]
>>> print(b<3)
[ True True True False]
元素乘法和矩阵乘法 元素乘法直接用* 矩阵乘法调用dot方法,或用运算符@
>>> import numpy as np
>>> a=np.array([[1,1],[0,1]])
>>> b=np.arange(4).reshape((2,2))
>>> print(a,b)
[[1 1]
[0 1]] [[0 1]
[2 3]]
>>> c=a*b
>>> c_dot=np.dot(a,b)
>>> print(c)
[[0 1]
[0 3]]
>>> print(c_dot)
[[2 4]
[2 3]]
>>> c_dot_2=a.dot(b)
>>> print(c_dot_2)
[[2 4]
[2 3]]
>>> c=a@b
>>> print(c)
[[2 4]
[2 3]]
默认情况下,这些操作适用于数组,就像它是一个数字列表一样,无论其形状如何。但是,通过指定axis 参数,您可以沿数组的指定轴应用操作:
>>> import numpy as np
>>> a=np.random.random((2,4))
>>> print(a)
[[0.05563761 0.04924205 0.64500476 0.19619684]
[0.1923783 0.95430332 0.91048974 0.35034246]]
>>> print(np.sum(a))
3.3535950824469234
>>> print(np.min(a))
0.04924205279628968
>>> print(np.max(a))
0.9543033211623287
>>> print(np.sum(a,axis=1)) #axis=1表示在行上操作,axis=0表示在列上操作
[0.94608126 2.40751382]
>>> print(np.min(a,axis=0))
[0.05563761 0.04924205 0.64500476 0.19619684]
>>> a.min()
0.04924205279628968
>>> a.max()
0.9543033211623287
>>> a.sum()
3.3535950824469234
索引、中位数、平均数、排序、转置
>>> import numpy as np
>>> A=np.arange(2,14).reshape((3,4))
>>> print(A)
[[ 2 3 4 5]
[ 6 7 8 9]
[10 11 12 13]]
#平均数
>>> print(np.argmin(A))
0
>>> print(np.argmax(A))
11
>>> print(np.mean(A))
7.5
>>> print(A.mean())
7.5
>>> print(np.average(A))
#中位数
>>> print(np.median(A))
7.5
#累加
>>> print(np.cumsum(A))
[ 2 5 9 14 20 27 35 44 54 65 77 90]
#累差
>>> print(np.diff(A))
[[1 1 1]
[1 1 1]
[1 1 1]]
>>> A=np.arange(14,2,-1).reshape((3,4))
>>> print(A)
[[14 13 12 11]
[10 9 8 7]
[ 6 5 4 3]]
>>> print(np.sort(A)) #排序
[[11 12 13 14]
[ 7 8 9 10]
[ 3 4 5 6]]
>>> print(np.transpose(A)) #矩阵转置
[[14 10 6]
[13 9 5]
[12 8 4]
[11 7 3]]
>>> print(A.T)
[[14 10 6]
[13 9 5]
[12 8 4]
[11 7 3]]
>>> print((A.T).dot(A)) #A转置*A
[[332 302 272 242]
[302 275 248 221]
[272 248 224 200]
[242 221 200 179]]
>>> print(np.clip(A,5,9)) #小于5的数都变成5,大于9的数都变成9
[[9 9 9 9]
[9 9 8 7]
[6 5 5 5]]
索引、切片和迭代
一维的数组可以进行索引、切片和迭代操作的,就像 列表 和其他Python序列类型一样。多维的数组每个轴可以有一个索引。
>>> import numpy as np
>>> A=np.arange(3,15)
>>> print(A)
[ 3 4 5 6 7 8 9 10 11 12 13 14]
>>> print(A[3])
6
>>> A=np.arange(3,15).reshape((3,4))
>>> print(A)
[[ 3 4 5 6]
[ 7 8 9 10]
[11 12 13 14]]
>>> print(A[2])
[11 12 13 14]
>>> print(A[1][1])
8
>>> print(A[1,1])
8
>>> print(A[2:])
[[11 12 13 14]]
>>> print(A[:,1])
[ 4 8 12]
>>> print(A[1,1:2])
[8]
>>> for row in A: #迭代行
print(row)
[3 4 5 6]
[ 7 8 9 10]
[11 12 13 14]
>>> for column in A.T: #迭代列
print(column)
[ 3 7 11]
[ 4 8 12]
[ 5 9 13]
[ 6 10 14]
>>> print(A.flatten()) #矩阵变成序列
[ 3 4 5 6 7 8 9 10 11 12 13 14]
>>> for item in A.flat: #迭代元素
print(item)
3
4
5
6
7
8
9
10
11
12
13
14
当提供的索引少于轴的数量时,缺失的索引被认为是完整的切片
>>> def f(x,y):
... return 10*x+y
...
>>> b = np.fromfunction(f,(5,4),dtype=int)
>>> b
array([[ 0, 1, 2, 3],
[10, 11, 12, 13],
[20, 21, 22, 23],
[30, 31, 32, 33],
[40, 41, 42, 43]])
>>> b[-1] # the last row. Equivalent to b[-1,:]
array([40, 41, 42, 43])
b[i] 方括号中的表达式 i 被视为后面紧跟着 : 的多个实例,用于表示剩余轴。NumPy也允许你使用三个点写为 b[i,…]。
三个点( … )表示产生完整索引元组所需的冒号。例如,如果 x 是rank为的5数组(即,它具有5个轴),则:
x[1,2,...] 相当于 x[1,2,:,:,:],
x[...,3] 等效于 x[:,:,:,:,3]
x[4,...,5,:] 等效于 x[4,:,:,5,:]。
>>> c = np.array( [[[ 0, 1, 2], # a 3D array (two stacked 2D arrays)
... [ 10, 12, 13]],
... [[100,101,102],
... [110,112,113]]])
>>> c.shape
(2, 2, 3)
>>> c[1,...] # same as c[1,:,:] or c[1]
array([[100, 101, 102],
[110, 112, 113]])
>>> c[...,2] # same as c[:,:,2]
array([[ 2, 13],
[102, 113]])
形状操纵
合并操作
>>> import numpy as np
>>> A=np.array([1,1,1])
>>> B=np.array([2,2,2])
>>> print(np.vstack((A,B))) #上下合并
[[1 1 1]
[2 2 2]]
>>> C=np.vstack((A,B))
>>> print(A.shape,C.shape)
(3,) (2, 3)
>>> D=np.hstack((A,B)) #左右合并
>>> print(D)
[1 1 1 2 2 2]
>>> print(A.T)
[1 1 1]
>>> print(A.T.shape)
(3,)
>>> print(A[np.newaxis,:]) #在行上增加维度
[[1 1 1]]
>>> print(A[np.newaxis,:].shape)
(1, 3)
>>> print(A[:,np.newaxis]) #在列上增加维度
[[1]
[1]
[1]]
>>> print(A[:,np.newaxis].shape)
(3, 1)
>>> A=np.array([1,1,1])[:,np.newaxis]
>>> B=np.array([2,2,2])[:,np.newaxis]
>>> C=np.vstack((A,B))
>>> D=np.hstack((A,B))
>>> print(C)
[[1]
[1]
[1]
[2]
[2]
[2]]
>>> print(D)
[[1 2]
[1 2]
[1 2]]
>>> C=np.concatenate((A,B,B,A)) #可以进行多项合并
>>> print(C)
[[1]
[1]
[1]
[2]
[2]
[2]
[2]
[2]
[2]
[1]
[1]
[1]]
>>> C=np.concatenate((A,B,B,A),axis=1)
>>> print(C)
[[1 2 2 1]
[1 2 2 1]
[1 2 2 1]]
分割操作
>>> import numpy as np
>>> A=np.arange(12).reshape((3,4))
>>> print(A)
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
>>> print(np.split(A,2,axis=1)) #等量分割
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
>>> print(np.split(A,3,axis=0))
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
>>> print(np.array_split(A,3,axis=1)) #不等量分割
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2],
[ 6],
[10]]), array([[ 3],
[ 7],
[11]])]
>>> print(np.vsplit(A,3)) #横向分割
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
>>> print(np.hsplit(A,2)) #纵向分割
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
拷贝和视图
>>> import numpy as np
>>> a=np.arange(4)
>>> a
array([0, 1, 2, 3])
>>> b=a
>>> c=a
>>> d=b
>>> a[0]=11
>>> a
array([11, 1, 2, 3])
>>> b is a #判断b是不是完全的a
True
>>> b
array([11, 1, 2, 3])
>>> c
array([11, 1, 2, 3])
>>> d
array([11, 1, 2, 3])
>>> d[1:3]=[22,33]
>>> a
array([11, 22, 33, 3])
>>> b
array([11, 22, 33, 3])
>>> c
array([11, 22, 33, 3])
>>> d
array([11, 22, 33, 3])
>>> b=a.copy() #a,,b不关联 deepcopy
>>> b
array([11, 22, 33, 3])
>>> a[3]=44
>>> a
array([11, 22, 33, 44])
>>> b
array([11, 22, 33, 3])