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

最后一次更新日期: 2019/3/7

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) 奇异值分解 -
ndarray.T 转置 对一维数组转置是无效的
(以下是部分示例)
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=(1,3,4)b.shape=(5,4,6),则np.dot(a,b).shape=(5,3,6),如果a.shape=(2,3,4),计算就会报错,因为不满足广播的规则。

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 非数值 -
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容