Python小推车

[python][科学计算][numpy]使用指南3-运算

2019-02-24  本文已影响23人  jiedawang

最后一次更新日期: 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.maxnp.min有对应的np.argmaxnp.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一致。

innerdot类似,但规则更简单,两个数组均以最后一个轴作为向量的轴,即最后一个轴长度要保持一致。例如,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) 交集 xy的公共元素
np.union1d(x, y) 并集 xy的所有元素
np.setdiff1d(x, y) 集合差 x中存在,y中不存在的元素
np.setxor1d(x, y) 集合异或 xy的独占元素

以上方法适用于一维数组。

(以下是部分示例)
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 非数值 -
上一篇 下一篇

猜你喜欢

热点阅读