数组操作
数值相关的操作
可以使用.sum()
方法进行求和:
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
a
array([[1, 2, 3],
[4, 5, 6]])
a.sum()
21
默认对所有元素求和,可以通过axis
参数指定求和维度:
a.sum(axis=0)
array([5, 7, 9])
a.sum(axis=1)
array([ 6, 15])
指定维度时,相当于沿着指定的维度进行求和,因此,对于形状为(2,3)的数组,指定第0维会将第0维消去,得到形状为(3,)的数组,指定第1维会将第1维消去,得到形状为(2,)的数组。
与之对应还有个np.sum()
函数,得到相同的操作结果:
np.sum(a)
21
该函数可以作用在与数组类似的对象上:
np.sum([[1, 2, 3], [4, 5, 6]])
21
.prod()
方法和np.prod()
函数可以实现求积操作,与.sum()
方法类似:
a.prod()
720
np.prod(a, axis=1)
array([ 6, 120])
.max()
和.min()
函数可以实现求最值的操作,也支持指定维度:
a.max()
6
a.min()
1
a.max(axis=-1)
array([3, 6])
a.min(axis=0)
array([1, 2, 3])
对应的函数形式分别为np.max()
和np.min()
。
.argmax()
和.argmin()
函数可以分别返回最大值和最小值的位置:
a.argmax()
5
a是一个(2,3)的数组,索引5是不存在的,.argmax()
方法返回的是将a看成一维数组时最大值的位置。
指定维度时,它返回的是对应维度中最值的位置:
a.argmin(axis=0)
array([0, 0, 0])
对应的函数形式分别为np.argmax()
和np.argmin()
。
均值.mean()
方法和np.mean()
函数:
a.mean()
3.5
a.mean(axis=1)
array([2., 5.])
标准差.std()
方法和np.std()
函数,方差.var()
方法和np.var()
函数:
a.std()
1.707825127659933
a.std(axis=1)
array([0.81649658, 0.81649658])
a.var()
2.9166666666666665
.round()
方法会将数组近似到整数:
a = np.array([1.35, 2.5, 1.5])
a.round()
array([1., 2., 2.])
形状相关的操作
使用.shape
属性可以直接修改数组的形状:
a = np.array([8, 6, 5, 7, 1, 4, 2, 3])
a.shape
(8,)
a
array([8, 6, 5, 7, 1, 4, 2, 3])
a.shape = 2, 4
a
array([[8, 6, 5, 7],
[1, 4, 2, 3]])
可以使用.reshape()
方法得到一个新数组,但是不改变原来的数组:
a.reshape(4, 2)
array([[8, 6],
[5, 7],
[1, 4],
[2, 3]])
a
array([[8, 6, 5, 7],
[1, 4, 2, 3]])
形状可以增加一个-1
参数,当某个维度为-1
时,NumPy
会自动根据其他维度计算:
a.reshape(-1, 2)
array([[8, 6],
[5, 7],
[1, 4],
[2, 3]])
可以调用.resize()
方法改变原来数组的形状:
a.resize(8)
a
array([8, 6, 5, 7, 1, 4, 2, 3])
.resize()
方法不支持-1
参数,但是支持形状不对应的修改,缺少的部分会补0
:
b = np.array([1, 2, 3, 4, 5, 6, 7, 8])
b.resize(2, 5)
b
array([[1, 2, 3, 4, 5],
[6, 7, 8, 0, 0]])
np.newaxis可以扩展数组的维度,通常配合索引使用,增加一个大小为1的新维度:
a = np.arange(3)
a.shape
(3,)
a[np.newaxis, :]
array([[0, 1, 2]])
a.shape
(3,)
a[np.newaxis, :, np.newaxis]
array([[[0],
[1],
[2]]])
a.shape
(3,)
np.newaxis
是None
的别名,也可以直接使用None
代替它:
np.newaxis is None
True
.squeeze()
方法返回一个去掉所有大小为1的维度的新数组,原数组不改变:
a.shape = 1, 3, 1
a
array([[[0],
[1],
[2]]])
a.squeeze()
array([0, 1, 2])
a.shape
(1, 3, 1)
数组的转置:
a = np.arange(30)
a.shape = 5, 6
a
array([[ 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]])
a.T
array([[ 0, 6, 12, 18, 24],
[ 1, 7, 13, 19, 25],
[ 2, 8, 14, 20, 26],
[ 3, 9, 15, 21, 27],
[ 4, 10, 16, 22, 28],
[ 5, 11, 17, 23, 29]])
a.transpose()
array([[ 0, 6, 12, 18, 24],
[ 1, 7, 13, 19, 25],
[ 2, 8, 14, 20, 26],
[ 3, 9, 15, 21, 27],
[ 4, 10, 16, 22, 28],
[ 5, 11, 17, 23, 29]])
a.shape = 1, 2, 3, 5
a.T.shape
(5, 3, 2, 1)
数组的连接操作
a = np.arange(6)
a.shape = 2, 3
a
array([[0, 1, 2],
[3, 4, 5]])
b = np.arange(10, 16)
b.shape = 2, 3
b
array([[10, 11, 12],
[13, 14, 15]])
连接两个数组可以使用np.concatenate()
函数:
x = np.concatenate((a, b))
x.shape
(4, 3)
x
array([[ 0, 1, 2],
[ 3, 4, 5],
[10, 11, 12],
[13, 14, 15]])
默认情况下,np.concatenate()
函数会沿着第0维开始进行连接。连接的维度可以通过axis
指定:
x = np.concatenate((a, b), axis=1)
x.shape
(2, 6)
理论上说,a和b的形状一样,还可以让他们沿着第2维进行连接,得到一个(2,3,2)的数组。但是np.concatenate()
函数不支持直接使用这个的操作。为了解决这个问题,可以使用np.atleast_1d(),np.atleast_2d(),np.atleast_3d()
函数将数组扩展:
x = np.concatenate(np.atleast_3d(a, b), axis=2)
x.shape
(2, 3, 2)
np.atleast_xd()
函数系列的运作规则如下:
np.atleast_xd()
函数系列对于大于等于x维的数组不起作用。- 对于形状为(N,)的数组,
np.atleast_2d()
函数将其转变为形状为(1,N)的数组。 - 对于形状为(N,)的数组,
np.atleast_3d()
函数将其转变为形状为(1,N,1)的数组。 - 对于形状为(M,N)的数组,
np.atleast_3d()
函数将其转变为形状为(M,N,1)的数组。
对于常用的沿着第0,1,2三维的操作,NumPy提供了以下三个函数np.vstack(),np.hstack(),np.dstack()
,完成各个方法的连接操作:
a.shape
(2, 3)
b.shape
(2, 3)
np.vstack((a, b))
array([[ 0, 1, 2],
[ 3, 4, 5],
[10, 11, 12],
[13, 14, 15]])
np.hstack((a, b))
array([[ 0, 1, 2, 10, 11, 12],
[ 3, 4, 5, 13, 14, 15]])
np.dstack((a, b))
array([[[ 0, 10],
[ 1, 11],
[ 2, 12]],
[[ 3, 13],
[ 4, 14],
[ 5, 15]]])
数组的四则运算,点乘和矩阵运算
a = np.array([[1, 2], [3, 4]])
四则运算:
a * a
array([[ 1, 4],
[ 9, 16]])
a + a
array([[2, 4],
[6, 8]])
a / a
array([[1., 1.],
[1., 1.]])
a - a
array([[0, 0],
[0, 0]])
a ** 2
array([[ 1, 4],
[ 9, 16]])
a + 2
array([[3, 4],
[5, 6]])
点乘,即矩阵运算:
a.dot(a)
array([[ 7, 10],
[15, 22]])
np.dot(a, a)
array([[ 7, 10],
[15, 22]])
Python 3提供了@
操作符完成点乘操作:
a @ a
array([[ 7, 10],
[15, 22]])
数组的数学操作
np.pi
3.141592653589793
三角函数:
a = np.linspace(0, np.pi, 4)
a
array([0. , 1.04719755, 2.0943951 , 3.14159265])
np.cos(a)
array([ 1. , 0.5, -0.5, -1. ])
np.exp(a)
array([ 1. , 2.84965391, 8.1205274 , 23.14069263])
np.sqrt(a)
array([0. , 1.02332671, 1.44720251, 1.77245385])
数组的逻辑与比较操作
a = np.arange(6)
a > 3
array([False, False, False, False, True, True])
a[a > 3]
array([4, 5])
a <= a
array([ True, True, True, True, True, True])
不能用 ==
符号判断两个数组是否相等:
a == a
array([ True, True, True, True, True, True])
判断相等需要用 np.all()
方法:
np.all(a == a)
True
不过考虑到浮点数的精度问题,所以一般用 np.allclose()
方法:
np.allclose(a, a)
True
np.nan
是一个特殊的值,它做判断的时候当False
用,且与任何数进行比较都是False
,包括它自己:
np.nan == np.nan
False
为了判断一个值是否为np.nan
,需要使用np.isnan()
函数:
np.isnan(np.nan)
True
b = np.array([np.inf, -np.inf, np.nan])
np.isnan(b)
array([False, False, True])