无法播放?请 点击这里 跳转到Youtube
切换视频源:
通过前两章的学习,我们已经学会了创建NumPy数组常用的函数,以及和索引相关的内容。这一章我们来更深入地学习NumPy中和数学相关的函数,帮助我们更好地掌握如何实现NumPy数组中的数学运算。
Arithmetic operations
首先我们来学习一下 NumPy中基本的算数运算,除了使用计算符号实现这类操作之外,我们还能直接使用NumPy自带的一些函数。
matrix1 = np.array([[1,2],[3,4]], dtype=np.float64)
matrix2 = np.array([[5,6],[7,8]], dtype=np.float64)
matrix1 + matrix2 # 加法
np.add(matrix1, matrix2)
[[ 6. 8.]
[10. 12.]]
matrix1 - matrix2 # 减法
np.add(matrix1, matrix2)
[[-4. -4.]
[-4. -4.]]
matrix1 * matrix2 # 相乘
np.multiply(matrix1, matrix2)
[[ 5. 12.]
[21. 32.]]
matrix1 / matrix2 # 相除
np.divide(matrix1, matrix2)
[[0.2 0.33333333]
[0.42857143 0.5 ]]
matrix2 // matrix1 # 整除
np.floor_divide(matrix2, matrix1)
[[5. 3.]
[2. 2.]]
matrix2 % matrix1 # 取余
np.mod(matrix2, matrix1)
[[0. 0.]
[1. 0.]]
matrix1 ** matrix2 # 幂运算
np.power(matrix1, matrix2)
[[1.0000e+00 6.4000e+01]
[2.1870e+03 6.5536e+04]]
Mathematical and statistical functions
除了简单的算数计算,NumPy也提供了许多和数学与统计相关的函数,帮助我们方便地获取相关的运算结果。
rand_matrix = (np.random.randint(10, 1000, size=(2,5)) - 500) / 10.0
[[ 20. 15.4 -12.8 -1.1 -8.8]
[-18.3 -19.6 20.2 -15.5 43.1]]
print(np.isnan(rand_matrix)) # 检测是否为nan
[[False False False False False]
[False False False False False]]
print(np.sign(rand_matrix)) # 检测每个元素的正负,正是1,负是-1
[[ 1. 1. -1. -1. -1.]
[-1. -1. 1. -1. 1.]]
print(np.nonzero(rand_matrix)) # 拿到数组中非零元素的位置,会返回非零元素的索引值位置
(array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1]), array([0, 1, 2, 3, 4, 0, 1, 2, 3, 4]))
print(np.ceil(rand_matrix)) # 拿到大于元素的最小整数
[[ 20. 16. -12. -1. -8.]
[-18. -19. 21. -15. 44.]]
print(np.cumsum(rand_matrix)) # 计算数组的累计和
[ 20. 35.4 22.6 21.5 12.7 -5.6 -25.2 -5. -20.5 22.6]
print(np.diff(rand_matrix)) # 计算数组的离散差值
[[ -4.6 -28.2 11.7 -7.7]
[ -1.3 39.8 -35.7 58.6]]
print(np.sqrt(matrix1)) # 计算数组的正平方根
[[4.47213595 3.92428337 nan nan nan]
[ nan nan 4.49444101 nan 6.56505902]]
print(np.square(rand_matrix)) # 计算数组的平方数
[[4.00000e+02 2.37160e+02 1.63840e+02 1.21000e+00 7.74400e+01]
[3.34890e+02 3.84160e+02 4.08040e+02 2.40250e+02 1.85761e+03]]
m2 = np.arange(10) * 2
np.sin(m2) # 计算数组的三角函数 sin
[ 0. 0.90929743 -0.7568025 -0.2794155 0.98935825 -0.54402111
-0.53657292 0.99060736 -0.28790332 -0.75098725]
print(np.sort(rand_matrix)) # 将数组进行排序
[[-12.8 -8.8 -1.1 15.4 20. ]
[-19.6 -18.3 -15.5 20.2 43.1]]
还有以下常用的统计函数:
matrix = np.arange(10).reshape(2, 5)
[[-5 -4 -3 -2 -1]
[ 0 1 2 3 4]]
matrix.mean() # 数组中的平均数: -0.5
np.median(matrix) # 数组中的中位数: -0.5
np.argmin(matrix) # 数组中最大数的索引值: 0
np.argmax(matrix) # 数组中最大数的索引值: 9
np.sum(matrix) # 计算所有元素相加的和: -5
np.abs(matrix) # 计算数组元素的绝对值
[[5 4 3 2 1]
[0 1 2 3 4]]
np.max(matrix) # 数组中最大的数: 4
np.sum(matrix) # 计算所有元素的和: -5
np.sum(matrix, axis=0) # 按列相加之和的数组
[-5 -3 -1 1 3]
np.sum(matrix, axis=1) # 按行相加之和的数组
[-15 10]
Linear Algebra
除了上面提到的基本数学计算,NumPy还支持和线性代数相关的计算操作,可以帮助我们非常方便地对矩阵进行相关操作。
matrix1 = np.arange(8).reshape(2, 4)
print(matrix)
[[0 1 2 3]
[4 5 6 7]]
print(matrix.T) # 转置矩阵 Tranpose
[[0 4]
[1 5]
[2 6]
[3 7]]
matrix2 = np.arange(5)
print(matrix2)
print(matrix2.T)
[[0 1 2 3 4]]
matrix3 = matrix2.reshape(1, 5)
print(matrix3)
print(matrix3.T)
[[0]
[1]
[2]
[3]
[4]]
矩阵乘法
matrix1 = np.arange(8).reshape(2, 4)
print(matrix1)
[[0 1 2 3]
[4 5 6 7]]
matrix2 = np.arange(8).reshape(4, 2)
print(matrix2)
[[0 1]
[2 3]
[4 5]
[6 7]]
print(matrix1.dot(matrix2)) # 矩阵积
[[28 34]
[76 98]]
numpy.linalg 模块中有很多线性代数相关函数。 使用这个模块,可以计算逆矩阵、求特征值、解线性方程组以及求解行列式等。
matrix = np.arange(9).reshape(3, 3)
inverse_matrix = np.linalg.inv(matrix) # 获得逆矩阵: 此语句会返回错误,因为该矩阵是Singular Matrix,所有没有相对性的逆矩阵
valid_matrix = np.array([[1,2,3],[5,7,11],[21,29,31]])
print(valid_matrix)
inverse_matrix = np.linalg.inv(valid_matrix) # 获得逆矩阵
print(inverse_matrix)
[[-2.31818182 0.56818182 0.02272727]
[ 1.72727273 -0.72727273 0.09090909]
[-0.04545455 0.29545455 -0.06818182]]
print(valid_matrix.dot(inverse_matrix)) # The product of a matrix by its inverse returns the identity matrix
[[ 1.00000000e+00 -1.66533454e-16 0.00000000e+00]
[ 6.31439345e-16 1.00000000e+00 -1.38777878e-16]
[ 5.21110932e-15 -2.38697950e-15 1.00000000e+00]]
print(np.eye(3)) # eye函数可以输出对角线为1的矩阵,函数内的参数代表1的个数
获得矩阵的行列式:
np.linalg.det(valid_matrix) # 获得矩阵的行列式: 43.9999
计算矩阵的特征值和右特征向量(Eigenvalues and eigenvectors)
eigenvalues, eigenvectors = np.linalg.eig(matrix) # 计算方阵的特征值和右特征向量
print(eigenvalues)
print(eigenvectors)
print(matrix.dot(eigenvectors) - eigenvalues * eigenvectors) # M.E1 - E2.E1 = 0
我们甚至还能直接使用NumPy自带的函数解决线性标量方程,比如我们可以使用下面的代码,给以下两个方程求解:
- 2x + 6y = 6
- 5x + 3y = -9
coeffs = np.array([[2,6],[5,3]])
depvars = np.array([6,-9])
solution = np.linalg.solve(coeffs, depvars) # 以矩阵形式解一个线性矩阵方程
print(solution) # array([-3., 2.])
coeffs.dot(solution), depvars # (array([ 6., -9.]), array([ 6, -9]))
Homework
将以下的两个不同形状的矩阵,进行矩阵的相乘,得到最终形状为(3,3)的矩阵。然后计算出数组中各个元素的正平方根,最后再将计算之后所有元素相加,得到一个和。
matrix1 = np.arange(15).reshape(3, 5)
matrix2 = np.arange(15).reshape(5, 3)
答案:
matrix3 = np.dot(matrix1, matrix2)
matrix3 = np.sqrt(matrix3)
total_sum =np.sum(matrix3)
print(total_sum) # 143.2015963354727