这一篇文章我们看一下numpy里array的基本运算。

降维操作

除了应用reshape可以改变一个array的维度,你可以用flatten把一个多维array变成一个一维的数组。
比如这样:


arr = np.arange(1,9).reshape((2,4))
print(arr)
print(arr.flatten())

这样你得到一个一维的数组:


[[1 2 3 4]
 [5 6 7 8]]
 
[1 2 3 4 5 6 7 8]

转置操作

转置就是将矩阵的行列互换,他是通过arr.T来完成的:


arr = np.arange(1,9).reshape((2,4))
print(arr)
print(arr.T)

结果是:


[[1 2 3 4]
 [5 6 7 8]]
 
[[1 5]
 [2 6]
 [3 7]
 [4 8]]

加减乘除

对于shape相同的数组,加减乘除就是对应位置的元素进行加减乘除:


a23 = np.ones((2,3))
b23 = np.ones((2,3))

print(a23,b23,c22)
print(a23+b23)
print(a23-b23)
print(a23*b23)
print(a23/b23)

得到结果为:


[[1. 1. 1.]
 [1. 1. 1.]]
 
[[1. 1. 1.]
 [1. 1. 1.]]
 
[[2. 2. 2.]
 [2. 2. 2.]]
 
[[0. 0. 0.]
 [0. 0. 0.]]
 
[[1. 1. 1.]
 [1. 1. 1.]]
 
[[1. 1. 1.]
 [1. 1. 1.]]

但是如果两个数组shape不同是无法进行加减乘除操作的,但是对于单个数字,行向量,列向量例外。

广播 broadcasting

广播的意思是,如果一个矩阵和一个数值,一个行向量,列向量进行进行加减乘除操作时,会自动把数值,行向量,列向量扩展到和矩阵同维度,然后进行计算。这些知识在我们后来进行神经网络的矩阵运算时会用到。


import numpy as np
A = np.zeros((3,3))
print(A)
print(A+1)
print(A+[2,2,2])
print(A+[[3],[3],[3]])

得到的结果为:


[[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]

[[1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]

[[2. 2. 2.]
 [2. 2. 2.]
 [2. 2. 2.]]

[[3. 3. 3.]
 [3. 3. 3.]
 [3. 3. 3.]]

array的一元运算

array不光能进行加减乘除,还可以进行次方,比如一个array的3次方可以用arr**3来表示。


arr = np.arange(1,4)
print(arr,arr**2)

结果为:


[1 2 3] [1 4 9]

我们也可以通过np的库对array进行一些其他运算,比如log,sin,abs等


arr = np.arange(1,4)
print(arr,np.log(arr),np.sin(arr))

结果为:


[1 2 3] [0. 0.69314718 1.09861229] [0.84147098 0.90929743 0.14112001]

array还可以进行boolen运算:


arr = np.arange(1,4)
print(arr,arr>2)

结果为:


[1 2 3] [False False  True]

数组还有一些统计计算,比如arr.sum(),arr.min(),arr.max()等操作。

dot运算

np.dot是对两个数组进行矩阵的乘法,如果两个操作数都是行向量,则进行的是向量的内积。


r=np.array([1,2,3])
print(r.dot(r))
c=r.reshape((3,1))
print(np.dot(r,c))

结果为:


14
[14]

上边的例子中,我们先用了r.dot(r),因为r为一个行向量,所以dot进行的是内积运算。结果为14。接着我们将r通过reshape编程三行一列的数组:


[[1]
 [2]
 [3]]

然后调用np.dot(r,c), 这种调用方式和r.dot(c)是一样的。这次进行的矩阵乘法,就是第一个矩阵的列数要等于第二个矩阵的行数,得到的结果是[14]。还有一点要注意就是矩阵乘法不满足交换律。r.dot(c) 和c.dot(r) 意义不同。

Axis

在numpy中,有的操作是可以针对不同的维度进行的。比如np.sum 操作,默认是对整个array进行求和,但是你如果指定了维度,它就可以在你定义的维度上求和。我们看一下例子:


arr = np.arange(1,9).reshape((2,4))
print(arr)
print(arr.sum())
print(arr.sum(axis=0))
print(arr.sum(axis=1))

结果为:


[[1 2 3 4]
 [5 6 7 8]]
 
36

[ 6  8 10 12]

[10 26]

当指定axis为0时,按列对数据求和,axis为1时,按行对数据求和。
在我们指定axis进行聚合的时候,默认情况下会改变ndarray的维度,比如原来是二维,聚合后成为一维。但是通过指定keepdims=True可以保留原来的维度。可以看一下下边的例子:


import numpy as np

arr = np.array([[1,2],[3,4]])
print(arr.sum(axis=0).ndim)
print(arr.sum(axis=0,keepdims=True).ndim)
print(arr.sum(axis=0).shape)
print(arr.sum(axis=0,keepdims=True).shape)

结果为:


1
2
(2,)
(1, 2)

矩阵的合并

矩阵的合并分为两种一种是垂直合并,水平合并。
垂直合并是vstack,水平合并是hstack。
我们看个列子:


arr1=np.array([[1,2],[3,4]])
arr2=np.array([[5,6],[7,8]])
print(np.vstack((arr1,arr2)))
print(np.hstack((arr1,arr2)))

结果为:


[[1 2]
 [3 4]
 [5 6]
 [7 8]]
 
[[1 2 5 6]
 [3 4 7 8]]

Array的拷贝

numpy的array之间的赋值都是引用的,如果你要复制一份值,必须调用copy方法:


a = np.array([1,2,3])
b = a
c = a.copy()
d = a[:-1]
a[0]=99
print(a)
print(b)
print(c)
print(d)

结果为:


[99  2  3]
[99  2  3]
[1 2 3]
[99  2]

替换数组中的值

可以用np.minimum 和 np.maximum来把数组中全部的数值和给定数值取最小值或者最大值。


import numpy as np
arr = np.random.randn(2,2)
print(arr)
print(np.maximum(arr,0))
print(np.minimum(arr,0))

结果为:


[[ 0.25956325  1.04774008]
 [ 0.79777211 -0.3229088 ]]
 
[[0.25956325 1.04774008]
 [0.79777211 0.        ]]
 
[[ 0.         0.       ]
 [ 0.        -0.3229088]]

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: