最后一次更新日期: 2019/2/27
NumPy 是一个 Python 包。 它代表 “Numeric Python”。 它是一个由多维数组对象(ndarray)和用于处理数组的例程集合组成的库。
使用NumPy,开发人员可以执行以下操作:
- 数组的算数和逻辑运算。
- 傅立叶变换和用于图形操作的例程。
- 与线性代数有关的操作。 NumPy 拥有线性代数和随机数生成的内置函数。
使用前先导入模块:
import numpy as np
1. 运算符
numpy对python中的运算符作了重载,可通过同样的用法实现数组运算。
数组与标量值的运算
In [191]: a=np.arange(0, 4)
In [192]: a
Out[192]: array([0, 1, 2, 3])
In [193]: a+1
Out[193]: array([1, 2, 3, 4])
In [193]: a*2
Out[194]: array([0, 2, 4, 6])
数组与数组的运算
In [199]: a1=np.arange(0, 4);a2=np.arange(4, 8)
In [200]: a1,a2
Out[200]: (array([0, 1, 2, 3]), array([4, 5, 6, 7]))
In [201]: a1+a2
Out[201]: array([ 4, 6, 8, 10])
In [202]: a2**a1
Out[202]: array([ 1, 5, 36, 343], dtype=int32)
2. 标量值函数
标量值函数会对数组中每一个元素进行同样的计算。
一元函数
函数 | 作用 | 说明 |
---|---|---|
np.abs | 绝对值 | 计算浮点数/整数/复数的绝对值 |
np.fabs | 绝对值 | 计算浮点数/整数的绝对值,速度更快(?) |
np.sqrt | 平方根 | x^0.5 |
np.square | 平方 | x^2 |
np.log | 自然对数 | - |
np.log2 | 2为底的对数 | - |
np.log10 | 10为底的对数 | |
np.log1p | x+1的自然对数 | 用于数值过小时保证计算的有效性 |
np.ceil | 向上取整 | - |
np.floor | 向下取整 | - |
np.rint | 舍入取整 | - |
np.around | 舍入指定位数 | 第二个参数decimals 为舍入位数 |
np.exp | 自然指数 | e^x |
np.sign | 符号值 | 三种值:1(正)、0(0)、-1(负) |
np.modf | 拆分小数和整数部分 | 以两个独立的数组方式返回 |
np.isnan | 判断是否为NaN | 返回bool型数组 |
np.isfinite | 判断是否是有穷 | 值非inf,非NaN;返回bool型数组 |
np.isinf | 判断是否是有穷 | 值为inf或-inf;返回bool型数组 |
np.sin,np.sinh | 正弦,双曲正弦 | - |
np.cos,np.cosh | 余弦,双曲余弦 | - |
np.tan,np.tanh | 正切,双曲正切 | - |
np.arcsin,np.arcsinh | 反正弦,反双曲正弦 | - |
np.arccos,np.arccosh | 反余弦,反双曲余弦 | - |
np.arctan,np.arctanh | 反正切,反双曲正切 | - |
np.logical_not | 逻辑非 | - |
多元函数
函数 | 作用 | 说明 |
---|---|---|
np.add(a1,a2) | 相加 | a1+a2 |
np.sub(a1,a2) | 相减 | a1-a2 |
np.multiply(a1,a2) | 相乘 | a1*a2 |
np.divide(a1,a2) | 相除 | a1/a2 |
np.power(a1,a2) | 乘幂 | a1**a2 |
np.floor_divide(a1,a2) | 整除 | a1//a2 |
np.mod(a1,a2) | 取模 | a1%a2 |
np.maxinum(a1,a2,a3) | 最大值 | 逐个元素进行比较,返回全部最大值的数组 |
np.fmax(a1,a2,a3) | 最大值(忽略NaN) | 逐个元素进行比较,返回全部最大值的数组 |
np.mininum(a1,a2,a3) | 最小值 | 逐个元素进行比较,返回全部最小值的数组 |
np.fmin(a1,a2,a3) | 最小值(忽略NaN) | 逐个元素进行比较,返回全部最小值的数组 |
np.copysign(a1,a2) | 复制符号 | 将a2的符号复制到a1中 |
np.greater(a1,a2) | 大于 | a1>a2 |
np.greater_equal(a1,a2) | 大于等于 | a1>=a2 |
np.less(a1,a2) | 小于 | a1<a2 |
np.less_equal(a1,a2) | 小于等于 | a1<=a2 |
np.equal(a1,a2) | 等于 | a1==a2 |
np.not_equal(a1,a2) | 不等于 | a1!=a2 |
np.logical_and(a1,a2) | 逻辑与 | - |
np.logical_or(a1,a2) | 逻辑或 | - |
np.logical_xor(a1,a2) | 逻辑异或 | - |
3. 聚合函数
聚合函数会减少数组的维数,通常可以指定一个轴方向axis
进行聚合,结果数组会减少一个维度,不指定方向时会在所有轴方向上聚合,结果为一个标量值。
大多数既可以静态调用,也可以直接调用ndarray对象的方法。
函数 | 作用 | 说明 |
---|---|---|
np.sum | 求和 | - |
np.mean | 平均值 | - |
np.max | 最大值 | - |
np.min | 最小值 | - |
np.prod | 连乘 | - |
np.any | 至少一个为True | 返回True/False |
np.all | 全部为True | 返回True/False |
np.max
和np.min
有对应的np.argmax
和np.argmin
的方法用于返回索引,详见查找章节。
(以下是部分示例)
np.sum
In [313]: a=np.array([[1,3],[4,2]])
In [314]: a
Out[314]:
array([[1, 3],
[4, 2]])
In [315]: a.sum()
Out[315]: 10
In [316]: a.sum(axis=0)
Out[316]: array([5, 5])
In [317]: a.sum(axis=1)
Out[317]: array([4, 6])
np.all
In [322]: a=np.array([[True,False],[True,True]])
In [323]: a
Out[323]:
array([[ True, False],
[ True, True]], dtype=bool)
In [324]: a.all()
Out[324]: False
In [325]: a.all(axis=0)
Out[325]: array([ True, False], dtype=bool)
4. 复合统计函数
函数 | 作用 | 说明 |
---|---|---|
np.cumsum | 累加 | - |
np.cumprod | 累乘 | - |
np.std | 标准差 | ((a-a.mean())**2).sum()/a.size |
np.var | 方差 | np.sqrt(((a-a.mean())**2).sum()/a.size) |
np.average | 加权平均数 | 第三个参数weights 为权重;ndarray无对应方法 |
np.bincount | 分箱计数 | 只支持整数,分箱区间根据最大最小值自动生成,间隔为1 |
np.histogram | 直方图统计 | 第二个参数bins 指定分箱方式,比np.bincount 更灵活 |
(以下是部分示例)
np.cumsum
In [317]: a=np.array([[1,3],[4,2]])
In [319]: a.cumsum()
Out[319]: array([ 1, 4, 8, 10], dtype=int32)
In [320]: a.cumsum(axis=0)
Out[320]:
array([[1, 3],
[5, 5]], dtype=int32)
np.average
In [331]: a=np.array([[1,3],[4,2]])
In [332]: w=np.array([[0.4,0.1],[0.2,0.3]])
In [333]: np.average(a)
Out[333]: 2.5
In [334]: np.average(a,weights=w)
Out[334]: 2.1000000000000001
5. 字符串函数
函数 | 作用 | 说明 |
---|---|---|
np.char.add | 字符串相加 | 逐个元素执行字符串相加 |
np.char.multiply | 字符串重复 | 第二个参数i 为重复次数 |
np.char.center | 字符串居中 | 第二个参数width 为长度,第三个参数fillchar 为填充字符 |
np.char.capitalize | 首字母大写 | - |
np.char.title | 单词首字母大写 | - |
np.char.lower | 转换为小写 | - |
np.char.upper | 转换为大写 | - |
np.char.split | 字符串分割 | 第二个参数sep 为分隔符,返回list<str>数组 |
np.char.splitlines | 行分割 | 以换行符分割,返回list<str>数组 |
np.char.strip | 移除头尾指定字符 | 第二个参数chars 为需要移除的字符 |
np.char.join | 以指定分隔符拼接字符 | 第一个参数sep 为分隔符 |
np.char.replace | 替换字符串 | 第二个参数old 为旧字符串,第三个参数new 为新字符串 |
np.char.decode | 解码 | 对每个元素调用str.decode |
np.char.encode | 编码 | 对每个元素调用str.encode |
(以下是部分示例)
np.char.add
In [301]: a1=np.array(['a','b']);a2=np.array(['c','d'])
In [302]: np.char.add(a1,a2)
Out[302]:
array(['ac', 'bd'],
dtype='<U2')
np.char.multiply
In [303]: a=np.array(['a','b'])
In [304]: np.char.multiply(a,3)
Out[304]:
array(['aaa', 'bbb'],
dtype='<U3')
np.char.center
In [305]: a=np.array(['a','b'])
In [306]: np.char.center(a,10,'*')
Out[306]:
array(['****a*****', '****b*****'],
dtype='<U10')
np.char.split
In [307]: a=np.array(['a,b','c,d'])
In [308]: np.char.split(a,',')
Out[308]: array([list(['a', 'b']), list(['c', 'd'])], dtype=object)
np.char.join
In [309]: a=np.array(['ab','cd'])
In [310]: np.char.join(',',a)
Out[310]:
array(['a,b', 'c,d'],
dtype='<U3')
In [311]: a=np.array(['a,b','c,d'])
In [312]: np.char.join(',',np.char.split(a,','))
Out[312]:
array(['a,b', 'c,d'],
dtype='<U3')
注意,该方法无法实现多维数组的聚合计算。在数组元素为字符串时,会对字符串中的每个元素进行拼接;在数组元素为字符串序列时,会对序列中的字符串进行拼接。
与split互为逆运算。
6. 线性代数运算
函数 | 作用 | 说明 |
---|---|---|
np.dot(a1,a2) | 点乘 | 多维数组下会将a1的最后一个轴和a2的倒数第二个轴作为向量的维度,可视作元素是向量的数组 |
np.vdot(a1,a2) | 向量点乘 | 高维数组会被展开计算 |
np.inner(a1,a2) | 向量内积 | 多维数组会将最后一个轴作为向量的维度 |
np.matmul(a1,a2) | 矩阵乘积 | 多维数组下会将最后两个轴作为矩阵的维度,可视作元素是矩阵的数组 |
np.linalg.det(a) | 行列式 | 行列式描述的是矩阵所表示的线性变换对“体积”的影响 |
np.linalg.solve(A,b) | 求解线性方程组 | 求解线性方程组Ax = b,A为系数矩阵(方阵),b为常数矩阵 |
np.linalg.lstsq(A,b) | 求解线性方程组 | 求线性方程组Ax = b的最小二乘解,A为系数矩阵,b为常数矩阵 |
np.linalg.inv(a) | 逆矩阵 | AB=BA=E,E为单位矩阵,则B为A的逆矩阵 |
np.linalg.pinv(a) | 广义逆矩阵 | 可以输入非方阵 |
np.linalg.eig(a) | 特征值和特征向量 | 返回两个数组 |
np.linalg.qr(a) | 正交分解 | - |
np.linalg.svd(a) | 奇异值分解 | - |
(以下是部分示例)
np.dot, np.vdot, np.inner, np.matmul
In [339]: a=np.array([1,2]);b=np.array([[3,4],[5,6]])
In [340]: np.dot(a,a), np.vdot(a,a), np.inner(a,a), np.matmul(a,a)
Out[340]: (5, 5, 5, 5)
In [341]: np.dot(a,b), np.dot(b,a)
Out[341]: (array([13, 16]), array([11, 17]))
In [342]: np.vdot(a,b)
Traceback (most recent call last):
File "<ipython-input-358-f2388a21d848>", line 1, in <module>
np.vdot(a,b)
ValueError: cannot reshape array of size 4 into shape (2,)
In [343]: np.inner(a,b), np.inner(b,a)
Out[343]: (array([11, 17]), array([11, 17]))
In [344]: np.matmul(a,b), np.matmul(b,a)
Out[344]: (array([13, 16]), array([11, 17]))
In [345]: np.dot(b,b)
Out[345]:
array([[29, 36],
[45, 56]])
In [346]: np.vdot(b,b)
Out[346]: 86
In [347]: np.inner(b,b)
Out[347]:
array([[25, 39],
[39, 61]])
In [348]: np.matmul(b,b)
Out[348]:
array([[29, 36],
[45, 56]])
这四个方法执行的运算都基于向量内积,非常相似,但在具体行为上有区别,很容易混淆。
dot
是将数组看作向量的集合,第一个数组的最后一个轴和第二个数组的倒数第二个轴作为向量的轴,抽取每个向量参与运算,因此这两个轴需要长度一致。例如,a.shape=(2,3,4)
,b.shape=(5,4,6)
,则np.dot(a,b).shape=(2,3,5,6)
。在二维情况下,实现的计算即是矩阵乘法。
vdot
的规则比较简单,会将数组展开为向量再计算点积,要求数组的size
一致。
inner
与dot
类似,但规则更简单,两个数组均以最后一个轴作为向量的轴,即最后一个轴长度要保持一致。例如,a.shape=(2,3,4)
,b.shape=(5,6,4)
,则np.dot(a,b).shape=(2,3,5,6)
。
matmul
的计算针对矩阵,和dot
一样在二维情况下表示矩阵乘法,二维以上视作矩阵的集合,参与运算的两个数组均以最后两个轴作为矩阵的轴。例如,a.shape=(2,3,4)
,b.shape=(5,4,6)
,则np.dot(a,b).shape=(2,5,3,6)
。
7. 集合运算
函数 | 作用 | 说明 |
---|---|---|
np.intersect1d(x, y) | 交集 |
x 和y 的公共元素 |
np.union1d(x, y) | 并集 |
x 和y 的所有元素 |
np.setdiff1d(x, y) | 集合差 |
x 中存在,y 中不存在的元素 |
np.setxor1d(x, y) | 集合异或 |
x 和y 的独占元素 |
以上方法适用于一维数组。
(以下是部分示例)
In [810]: x=np.array([1,3,4])
In [811]: y=np.array([2,3,5])
In [812]: np.intersect1d(x,y)
Out[812]: array([3])
In [813]: np.union1d(x,y)
Out[813]: array([1, 2, 3, 4, 5])
In [814]: np.setdiff1d(x,y)
Out[814]: array([1, 4])
In [815]: np.setxor1d(x,y)
Out[815]: array([1, 2, 4, 5])
8. 位运算
函数 | 作用 | 说明 |
---|---|---|
np.invert | 按位取反 | 等效于~ 运算符 |
np.bitwise_and | 按位与 | 等效于& 运算符 |
np.bitwise_or | 按位或 | 等效于| 运算符 |
np.bitwise_xor | 按位异或 | 等效于…… 运算符 |
np.left_shift | 位左移 | 等效于<< 运算符 |
np.right_shift | 位右移 | 等效于>> 运算符 |
(以下是部分示例)
In [858]: a=np.array([2,3,5,8,13])
In [859]: b=np.array([3,4,7,11,18])
In [860]: np.invert(a)
Out[860]: array([ -3, -4, -6, -9, -14], dtype=int32)
In [862]: bin(a[4]),bin(~a[4])
Out[862]: ('0b1101', '-0b1110')
In [863]: np.bitwise_and(a,b)
Out[863]: array([2, 0, 5, 8, 0], dtype=int32)
bin(a[3]),bin(b[3]),bin(a[3]&b[3])
Out[865]: ('0b1000', '0b1011', '0b1000')
np.invert
对于有符号整数,取对应二进制数的补码,然后 +1。二进制数形式的最高位为0表示正数,最高位为 1 表示负数。
9. 广播
numpy在进行不同形状的数组之间的计算时,会自动沿长度不足且长度为1的轴方向进行广播。当维数不一致时,会向前补齐,这要求后面的轴长度相同或是有一方长度等于1,即从后至前进行轴长比对,例如形状(a,b,c)与(b,c)可计算,(a,b,c)与(b,1)可计算,(a,b,c)与(a,b,1)可计算,(a,b,c)与(a,b)不可计算,(a,b,c)与(a,c,b)不可计算。
In [414]: a1=np.zeros((2,3,4))
...: a2=np.random.randint(0,10,(3,4))
...: a3=np.random.randint(0,10,(2,3))
...: a4=np.random.randint(0,10,(2,3,1))
In [418]: a1+a2
Out[418]:
array([[[ 3., 6., 0., 6.],
[ 9., 6., 3., 4.],
[ 2., 3., 1., 5.]],
[[ 3., 6., 0., 6.],
[ 9., 6., 3., 4.],
[ 2., 3., 1., 5.]]])
In [419]: a1+a3
Traceback (most recent call last):
File "<ipython-input-419-d778f9717621>", line 1, in <module>
a1+a3
ValueError: operands could not be broadcast together with shapes (2,3,4) (2,3)
In [420]: a1+a4
Out[420]:
array([[[ 0., 0., 0., 0.],
[ 9., 9., 9., 9.],
[ 1., 1., 1., 1.]],
[[ 4., 4., 4., 4.],
[ 0., 0., 0., 0.],
[ 2., 2., 2., 2.]]])
10. 常量
属性名 | 常量名 | 值 |
---|---|---|
np.e | 自然指数 | 2.718281828459045 |
np.pi | 圆周率 | 3.141592653589793 |
np.euler_gamma | 欧拉常数 | 0.5772156649015329 |
np.inf | 无穷大 | - |
np.nan | 非数值 | - |
网友评论