import numpy as np
线性代数
线性代数(如矩阵乘法、矩阵分解、行列式以及其他方阵数学等)是任何数组库的重要组成部分。不像某些语言,通过 * 对两个二维数组相乘得到的是一个元素级的积,而不是一个矩阵点积。因此,NumPy提供了一个用于矩阵乘法的dot函数(既是一个数组方法也是numpy命名空间中的一个函数):
In [2]:
x = np.array([[1.,2.,3.],[4.,5.,6.]])
y = np.array([[6.,23.],[-1,7],[8,9]])
x
Out[2]:
array([[1., 2., 3.],
[4., 5., 6.]])
In [3]:
y
Out[3]:
array([[ 6., 23.],
[-1., 7.],
[ 8., 9.]])
In [4]:
x.dot(y)
Out[4]:
array([[ 28., 64.],
[ 67., 181.]])
In [5]:
np.dot(x,y)
Out[5]:
array([[ 28., 64.],
[ 67., 181.]])
一个二维数组跟一个大小合适的一维数组的矩阵点积运算之后将会得到一个一维数组:
In [8]:
np.dot(x,np.ones(3))
Out[8]:
array([ 6., 15.])
In [10]:
np.dot(y,np.ones(2))
Out[10]:
array([29., 6., 17.])
numpy.linalg中有一组标准的矩阵分解运算以及求逆和行列式之类的东西。它们跟其他数据统计语言所使用的是相同的行业标准级Fortran库:
In [21]:
from numpy.linalg import inv,qr
X = np.random.randn(5,5)
mat = X.T.dot(X)
inv(mat)
Out[21]:
array([[ 2.84983031, 0.17028597, 2.06756515, -0.66935204, -0.72098659],
[ 0.17028597, 1.42661145, -0.53692364, -0.26180322, 1.0091138 ],
[ 2.06756515, -0.53692364, 2.11454618, -0.25328772, -1.24664562],
[-0.66935204, -0.26180322, -0.25328772, 0.40703488, -0.15416442],
[-0.72098659, 1.0091138 , -1.24664562, -0.15416442, 1.25974655]])
In [22]:
mat.dot(inv(mat))
Out[22]:
array([[ 1.00000000e+00, 7.84262679e-16, 5.68541151e-16,
5.30052302e-17, 1.89786553e-16],
[ 9.41383255e-16, 1.00000000e+00, -2.45387387e-16,
-1.53788812e-16, -2.64602775e-16],
[ 2.84351616e-15, 1.06673485e-16, 1.00000000e+00,
5.29432642e-16, -1.43437516e-16],
[-3.45062936e-15, 1.30806360e-15, -1.08754934e-15,
1.00000000e+00, 6.97169316e-16],
[-1.13189072e-16, 2.33564351e-15, -1.36478095e-16,
-9.00947159e-17, 1.00000000e+00]])
In [23]:
q,r = qr(mat)
r
Out[23]:
array([[-6.81664789, 0.89040141, 8.38335228, -5.35686432, 3.1113743 ],
[ 0. , -5.65482912, 6.94355581, 6.13809956, 12.75720191],
[ 0. , 0. , -2.56251774, -4.50210436, -3.11283249],
[ 0. , 0. , 0. , -1.1517615 , 0.06788782],
[ 0. , 0. , 0. , 0. , 0.46111917]])
diag 以一维数组的形式返回方阵的对角线(或非对角线)元素,或将一维数组转换为方阵(非对角线元素为0)
In [28]:
np.diag(x)
Out[28]:
array([1., 5.])
trace 计算对角线元素的和
In [29]:
np.trace(x)
Out[29]:
6.0
det 计算矩阵行列式
from numpy.linalg import det arr = np.array([[1,2],[3,4]]) det(arr)
eig 计算方阵的本征值和本征向量
In [36]:
np.linalg.eig(arr)
Out[36]:
(array([-0.37228132, 5.37228132]),
array([[-0.82456484, -0.41597356],
[ 0.56576746, -0.90937671]]))
inv 计算方阵的逆
In [37]:
np.linalg.inv(arr)
Out[37]:
array([[-2. , 1. ],
[ 1.5, -0.5]])
pinv 计算矩阵的Moore-Penrose伪逆
In [39]:
np.linalg.pinv(x)
Out[39]:
array([[-0.94444444, 0.44444444],
[-0.11111111, 0.11111111],
[ 0.72222222, -0.22222222]])
qr 计算QR分解
In [41]:
np.linalg.qr(x.dot(y))
Out[41]:
(array([[-0.385593 , -0.92266897],
[-0.92266897, 0.385593 ]]),
array([[ -72.61542536, -191.68103652],
[ 0. , 10.7415194 ]]))
svd 计算奇异值分解(SVD)
In [43]:
np.linalg.svd(x.dot(y))
Out[43]:
(array([[-0.3399534 , -0.94044228],
[-0.94044228, 0.3399534 ]]),
array([205.22074464, 3.80078535]),
array([[-0.35341616, -0.9354662 ],
[-0.9354662 , 0.35341616]]))
solve 解线性方程组Ax=b,其中A为一个方阵
In [52]:
np.linalg.solve(arr,np.array([6,8]))
Out[52]:
array([-4., 5.])
lstsq 计算Ax=b的最小二乘解
In [72]:
x = np.array([0, 1, 2, 3])
y = np.array([1, 1, 1, 3.1])
A = np.vstack([x, np.ones(len(x))]).T
m, c = np.linalg.lstsq(A, x, rcond=None)[0]
In [73]:
import matplotlib.pyplot as plt
_ = plt.plot(x, y, 'o', label='Original data', markersize=10)
_ = plt.plot(x, m*x + c, 'r', label='Fitted Line')
_ = plt.legend()
plt.show()