彻底剖析numpy的数值运算
2017-11-22 21:10
239 查看
彻底剖析numpy的数值运算
1.矢量与标量的运算
>>> a = np.array([1, 2, 3, 4]) >>> a + 1 array([2, 3, 4, 5]) >>> 2**a array([ 2, 4, 8, 16])
2.矢量之间进行点运算
>>> b = np.ones(4) + 1 >>> a - b array([-1., 0., 1., 2.]) >>> a * b array([ 2., 4., 6., 8.]) >>> j = np.arange(5) >>> 2**(j + 1) - j array([ 2, 3, 6, 13, 28])
当然,numpy对于这些操作都做了十分细致的优化。
>>> a = np.arange(10000) >>> %timeit a + 1 10000 loops, best of 3: 24.3 us per loop >>> l = range(10000) >>> %timeit [i+1 for i in l] 1000 loops, best of 3: 861 us per loop
值得注意的是,两个array之间进行*运算,并不是进行矩阵相乘(如果想进行矩阵间相乘,应该调用dot()方法)。
>>> c = np.ones((3, 3)) >>> c * c # NOT matrix multiplication! array([[ 1., 1., 1.], [ 1., 1., 1.], [ 1., 1., 1.]]) >>> c.dot(c) array([[ 3., 3., 3.], [ 3., 3., 3.], [ 3., 3., 3.]])
3.比较运算
>>> a = np.array([1, 2, 3, 4]) >>> b = np.array([4, 2, 2, 4]) >>> a == b array([False, True, False, True], dtype=bool) >>> a > b array([False, False, True, False], dtype=bool)
>>> a = np.array([1, 2, 3, 4]) >>> b = np.array([4, 2, 2, 4]) >>> c = np.array([1, 2, 3, 4]) >>> np.array_equal(a, b) False >>> np.array_equal(a, c) True
4.逻辑运算
>>> a = np.array([1, 1, 0, 0], dtype=bool) >>> b = np.array([1, 0, 1, 0], dtype=bool) >>> np.logical_or(a, b) array([ True, True, True, False], dtype=bool) >>> np.logical_and(a, b) array([ True, False, False, False], dtype=bool)
5.超越函数
>>> a = np.arange(5) >>> np.sin(a) array([ 0. , 0.84147098, 0.90929743, 0.14112001, -0.7568025 ]) >>> np.log(a) array([ -inf, 0. , 0.69314718, 1.09861229, 1.38629436]) >>> np.exp(a) array([ 1. , 2.71828183, 7.3890561 , 20.08553692, 54.59815003])
6.转置操作
>>> a = np.triu(np.ones((3, 3)), 1) # see help(np.triu) >>> a array([[ 0., 1., 1.], [ 0., 0., 1.], [ 0., 0., 0.]]) >>> a.T array([[ 0., 0., 0.], [ 1., 0., 0.], [ 1., 1., 0.]])
请注意!!转置操作返回的是原array的视图,即两者共享内存。
7.求和聚合
>>> x = np.array([1, 2, 3, 4]) >>> np.sum(x) 10 >>> x.sum() 10
或者,分别对每一行/列进行求和聚合:
>>> x = np.array([[1, 1], [2, 2]]) >>> x array([[1, 1], [2, 2]]) >>> x.sum(axis=0) # 列聚合 array([3, 3]) >>> [x[:, 0].sum(), x[:, 1].sum()] # ←相当于 [3, 3] >>> x.sum(axis=1) # 行聚合 array([2, 4]) >>> [x[0, :].sum(), x[1, :].sum()] # ←相当于 [2, 4]
相同地,求和聚合也适用于更高维度的情况:
>>> x = np.array([[[1, 2], [3, 4]],[[5, 6], [7, 8]]]) >>> x.sum(axis=2) [[ 3 7] [11 15]] >>> [[x[0, 0, :].sum(), x[0, 1, :].sum()], [x[1, 0, :].sum(), x[1, 1, :].sum()]] # ←相当于 [[3, 7], [11, 15]]
8.其他聚合操作
其他聚合操作的用法与上面介绍的求和聚合大同小异:8.1.求极值
>>> x = np.array([1, 3, 2]) >>> x.min() 1 >>> x.max() 3 >>> x.argmin() # 最小值的索引下标 0 >>> x.argmax() # 最大值的索引下标 1
8.2.逻辑聚合
>>> np.all([True, True, False]) # 相当于所有元素进行and的reduce操作 False >>> np.any([True, True, False]) # 相当于所有元素进行or的reduce操作 True
逻辑聚合常常与比较运算一起使用:
>>> a = np.zeros((100, 100)) >>> np.any(a != 0) False >>> np.all(a == a) True >>> a = np.array([1, 2, 3, 2]) >>> b = np.array([2, 2, 3, 2]) >>> c = np.array([6, 4, 4, 5]) >>> ((a <= b) & (b <= c)).all() True
8.3.其他统计值
>>> x = np.array([1, 2, 3, 1]) >>> y = np.array([[1, 2, 3], [5, 6, 1]]) >>> x.mean() 1.75 >>> np.median(x) 1.5 >>> np.median(y, axis=-1) # 最后一维,即进行行聚合 array([ 2., 5.]) >>> x.std() # 求标准差 0.82915619758884995
9.广播机制
对于不同维度大小的array,同样可以进行运算,可以视作是低维度array对于高维度array的“广播”或者“扩散”。>>> a = np.tile(np.arange(0, 40, 10), (3, 1)).T >>> a array([[ 0, 0, 0], [10, 10, 10], [20, 20, 20], [30, 30, 30]]) >>> b = np.array([0, 1, 2]) >>> a + b array([[ 0, 1, 2], [10, 11, 12], [20, 21, 22], [30, 31, 32]])
如果还是不理解,可以参考下图,以下的三个矩阵运算在广播机制的作用下其实是一样的:
“广播机制”还存在于赋值运算中,下面的小技巧可谓方便且实用:
>>> a = np.ones((4, 5)) >>> a array([[ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.]]) >>> a[0] = 2 >>> a array([[ 2., 2., 2., 2., 2.], [ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.]])
10.shape操作
10.1.展开操作(ravel)
将任意shape的array统一展开为一个一维array>>> a = np.array([[1, 2, 3], [4, 5, 6]]) >>> a.ravel() array([1, 2, 3, 4, 5, 6]) >>> a.T array([[1, 4], [2, 5], [3, 6]]) >>> a.T.ravel() array([1, 4, 2, 5, 3, 6])
10.2.Reshape操作
Reshape操作可以看作是ravel的逆操作>>> a.shape (2, 3) >>> b = a.ravel() >>> b = b.reshape((2, 3)) >>> b array([[1, 2, 3], [4, 5, 6]])
或者直接对原始array进行Reshape操作
>>> a.reshape((2, -1)) # -1代表该数值根据a的元素总数动态计算得出 array([[1, 2, 3], [4, 5, 6]])
!!!值得注意的是:reshape()函数的返回值有可能是视图,也有可能是全新的拷贝
10.3.维度追加
如果使用np.newaxis对象作为array的索引下标,就可以进行追加维度的操作。>>> z = np.array([1, 2, 3]) >>> z array([1, 2, 3]) >>> z[:, np.newaxis] # 相当于z.reshape((3, 1)) array([[1], [2], [3]]) >>> z[np.newaxis, :] # 相当于z.reshape((1, 3)) array([[1, 2, 3]])
10.4.维度替换
>>> a = np.arange(4*3*2).reshape(4, 3, 2) >>> a.shape (4, 3, 2) >>> a[0, 2, 1] 5 >>> b = a.transpose(1, 2, 0) >>> b.shape (3, 2, 4) >>> b[2, 1, 0] 5
当然,维度替换的返回值是毋庸置疑的视图。
10.5.Resize操作
它的用法和作用与Reshape操作相类似>>> a = np.arange(4) >>> a.resize((8,)) >>> a array([0, 1, 2, 3, 0, 0, 0, 0])
但是它只能用于只有一个引用变量的array,否则会报错:
>>> b = a >>> a.resize((4,)) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: cannot resize an array that has been referenced or is referencing another array in this way. Use the resize function
11.排序操作
以某个维度为轴进行排序操作:>>> a = np.array([[4, 3, 5], [1, 2, 1]]) >>> b = np.sort(a, axis=1) >>> b array([[3, 4, 5], [1, 1, 2]])
也可以获取排序后各元素在原array中的索引下标:
>>> a = np.array([4, 3, 1, 2]) >>> j = np.argsort(a) >>> j array([2, 3, 1, 0]) >>> a[j] array([1, 2, 3, 4])
相关文章推荐
- 彻底剖析numpy的数据类型
- Numpy包中两种常见数值运算类型array和mat比较
- NumPy常用【数值计算】函数总结(2):ufunc运算、矩阵运算
- 极好的运算放大器基础-彻底剖析运放疑难杂症
- 彻底剖析numpy的array对象
- 利用位运算求数值的整数次方
- SQL学习之连接符,数值运算,函数
- Shell 学习(三、vi变量和数值运算,父shell和子shell)
- 【PHP内核】语法:不同类型之间数值运算的实现
- 字符进行数值运算
- 数值的运算与处理器字长的关系
- JS 数值运算相关的极限值
- FrameSet 与 IFrame 彻底剖析
- numpy--prod和pad运算
- Numpy学习笔记3-数组的运算
- shell之数值运算
- numpy 的三角函数运算
- 数值运算工具Fortran(1)
- 高精度数值运算C++版本
- 【计算机视觉】【图像处理】图像数字化运算(Numpy)