对数组做基本的算术运算,将会对整个数组的所有元组进行逐一运算,并将运算结果保存在一个新的数组内,而不会破坏原始的数组。
>>> a = np.array( [20,30,40,50] ) >>> b = np.arange( 4 ) >>> b array([0, 1, 2, 3]) >>> c = a-b >>> c array([20, 29, 38, 47]) >>> b**2 array([0, 1, 4, 9]) >>> 10*np.sin(a) array([ 9.12945251, -9.88031624, 7.4511316 , -2.62374854]) >>> a<35 array([ True, True, False, False])
考虑一个问题,计算b的平方很好理解,各个元素自己算平方就好了。那么对于a-b这种,如果a和b的形状不一样呢?比如a长度为5,b长度为6:
>>> a = np.arange(5) >>> b = np.arange(6) >>> a,b (array([0, 1, 2, 3, 4]), array([0, 1, 2, 3, 4, 5])) >>> c=a-b ValueError Traceback (most recent call last) <ipython-input-27-508c408ffd98> in <module>() ----> 1 c=a-b ValueError: operands could not be broadcast together with shapes (5,) (6,)
结果是弹出异常!不能这么操作!
另外,不同于数学中的矩阵乘法,使用星号做乘号时,numpy对数组的每个元素,一一对应的做乘法。如果要进行矩阵的乘法怎么办?使用@
或者dot
函数!
>>> A = np.array( [[1,1], ... [0,1]] ) >>> B = np.array( [[2,0], ... [3,4]] ) >>> A * B # 元素间相乘 array([[2, 0], [0, 4]]) >>> A @ B #矩阵乘法 array([[5, 4], [3, 4]]) >>> A.dot(B) # 矩阵乘法 array([[5, 4], [3, 4]])
对于+=
和 *=
这一类操作符,会修改原始的数组,而不是新建一个:
>>> a = np.ones((2,3), dtype=int) >>> b = np.random.random((2,3)) >>> a *= 3 >>> a array([[3, 3, 3], [3, 3, 3]]) >>> b += a >>> b array([[ 3.417022 , 3.72032449, 3.00011437], [ 3.30233257, 3.14675589, 3.09233859]]) >>> a += b # b不会自动地转换为整数类型,所以弹出异常 Traceback (most recent call last): ... TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int64') with casting rule 'same_kind'
当对两个不同类型的数组进行运算操作时,将根据精度,选择最复杂的作为结果的类型:
>>> a = np.ones(3, dtype=np.int32) >>> b = np.linspace(0,pi,3) >>> b.dtype.name 'float64' >>> c = a+b >>> c array([ 1. , 2.57079633, 4.14159265]) >>> c.dtype.name 'float64' >>> d = np.exp(c*1j) >>> d array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j, -0.54030231-0.84147098j]) >>> d.dtype.name 'complex128'
许多一元操作(例如计算数组中所有元素的总和)都作为ndarray类的方法实现:
>>> a = np.random.random((2,3)) >>> a array([[ 0.18626021, 0.34556073, 0.39676747], [ 0.53881673, 0.41919451, 0.6852195 ]]) >>> a.sum() # 计算所有元素的总和 2.5718191614547998 >>> a.min() #找出最小值 0.1862602113776709 >>> a.max() #找出最大值 0.6852195003967595v
默认情况下,这些操作都会应用于整个数组,就好像它是一个数字列表,而不管其形状如何。但是,通过指定轴参数,可以沿数组的指定轴应用操作:
>>> b = np.arange(12).reshape(3,4) >>> b array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> >>> b.sum(axis=0) # 对每一列进行求和 array([12, 15, 18, 21]) >>> >>> b.min(axis=1) # 找出每一行的最小值 array([0, 4, 8]) >>> >>> b.cumsum(axis=1) # 对每行进行循环累加 array([[ 0, 1, 3, 6], [ 4, 9, 15, 22], [ 8, 17, 27, 38]])
可以使用sort方法对数组或数组某一维度进行就地排序,这会修改数组本身。
>>> a = np.array([[1,6,2],[6,1,3],[1,5,2]]) >>> b=a >>> b.sort() >>> b array([[1, 2, 6], [1, 3, 6], [1, 2, 5]]) >>> a array([[1, 2, 6], [1, 3, 6], [1, 2, 5]]) >>> a = np.array([[1,6,2],[6,1,3],[1,5,2]]) >>> a array([[1, 6, 2], [6, 1, 3], [1, 5, 2]]) >>> a.sort(axis=1) >>> a array([[1, 2, 6], [1, 3, 6], [1, 2, 5]]) >>> a = np.array([[1,6,2],[6,1,3],[1,5,2]]) >>> a.sort(axis=0) >>> a array([[1, 1, 2], [1, 5, 2], [6, 6, 3]])