线性代数

线性代数(如矩阵乘法、矩阵分解、行列式以及其他方阵数学等)是任何数组库的重要组成部分。不像某些语言(如 MATLAB),通过*对两个二维数组相乘得到的是一个元素级的积,而不是一个矩阵点积。因此,NumPy 提供了一个用于矩阵乘法的 dot 函数(既是一个数组方法也是 numpy 命名空间中的一个函数):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
In [223]: x = np.array([[1., 2., 3.], [4., 5., 6.]])

In [224]: y = np.array([[6., 23.], [-1, 7], [8, 9]])

In [225]: x
Out[225]:
array([[ 1., 2., 3.],
[ 4., 5., 6.]])

In [226]: y
Out[226]:
array([[ 6., 23.],
[ -1., 7.],
[ 8., 9.]])

In [227]: x.dot(y)
Out[227]:
array([[ 28., 64.],
[ 67., 181.]])

x.dot(y)等价于np.dot(x, y)

1
2
3
4
In [228]: np.dot(x, y)
Out[228]:
array([[ 28., 64.],
[ 67., 181.]])

一个二维数组跟一个大小合适的一维数组的矩阵点积运算之后将会得到一个一维数组:

1
2
In [229]: np.dot(x, np.ones(3))
Out[229]: array([ 6., 15.])

@符(类似 Python 3.5)也可以用作中缀运算符,进行矩阵乘法:

1
2
In [230]: x @ np.ones(3)
Out[230]: array([ 6., 15.])

numpy.linalg 中有一组标准的矩阵分解运算以及诸如求逆和行列式之类的东西。它们跟 MATLAB 和 R 等语言所使用的是相同的行业标准线性代数库,如 BLAS、LAPACK、Intel MKL(Math Kernel Library,可能有,取决于你的 NumPy 版本)等:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
In [231]: from numpy.linalg import inv, qr

In [232]: X = np.random.randn(5, 5)

In [233]: mat = X.T.dot(X)

In [234]: inv(mat)
Out[234]:
array([[ 933.1189, 871.8258, -1417.6902, -1460.4005, 1782.1391],
[ 871.8258, 815.3929, -1325.9965, -1365.9242, 1666.9347],
[-1417.6902, -1325.9965, 2158.4424, 2222.0191, -2711.6822],
[-1460.4005, -1365.9242, 2222.0191, 2289.0575, -2793.422 ],
[ 1782.1391, 1666.9347, -2711.6822, -2793.422 , 3409.5128]])

In [235]: mat.dot(inv(mat))
Out[235]:
array([[ 1., 0., -0., -0., -0.],
[-0., 1., 0., 0., 0.],
[ 0., 0., 1., 0., 0.],
[-0., 0., 0., 1., -0.],
[-0., 0., 0., 0., 1.]])

In [236]: q, r = qr(mat)

In [237]: r
Out[237]:
array([[-1.6914, 4.38 , 0.1757, 0.4075, -0.7838],
[ 0. , -2.6436, 0.1939, -3.072 , -1.0702],
[ 0. , 0. , -0.8138, 1.5414, 0.6155],
[ 0. , 0. , 0. , -2.6445, -2.1669],
[ 0. , 0. , 0. , 0. , 0.0002]])

表达式X.T.dot(X)计算X和它的转置X.T的点积。

表 4-7 中列出了一些最常用的线性代数函数。