10. NumPy矩阵运算

本章介绍一些NumPy下的矩阵或者向量的运算函数。

一个行向量乘以一个列向量称作向量的内积,又叫作点积,结果是一个数; 一个列向量乘以一个行向量称作向量的外积,外积是一种特殊的克罗内克积,结果是一个矩阵。

10.1 矩阵的乘法

在Numpy里有很多函数可以实现矩阵的乘法计算。

1). 使用matmul来实现两个矩阵的乘法计算,数学公式如下所示。

$C_{m \times q} = A_{m \times q} \times B_{q \times n}$ 注意两矩阵能相乘,要求A的列等于B的行

import numpy as np
a = np.arange(1, 7).reshape([2, 3])
b = np.arange(2, 8).reshape([3, 2])
print np.matmul(a, b),"# matmul(a, b)"

程序执行结果如下:

[[28 34]
 [64 79]] # matmul(a, b)

2). Numpy里的dot函数也可以对二维及以上的矩阵进行矩阵乘法运算。

import numpy as np
a = np.arange(1, 7).reshape([2, 3])
b = np.arange(2, 11).reshape([3, 3])
print np.matmul(a, b),"# matmul(a, b)"
print a, "# a"
print b, "# b"
print np.dot(a, b), "# dot(a, b)"

程序执行结果:

[[ 36  42  48]
 [ 81  96 111]] # matmul(a, b)
[[1 2 3]
 [4 5 6]] # a
[[ 2  3  4]
 [ 5  6  7]
 [ 8  9 10]] # b
[[ 36  42  48]
 [ 81  96 111]] # dot(a, b)

从结果可以看出用matmul和dot都能实现对a和b矩阵的乘法计算。

3). 使用NumPy里的inner函数也能实现矩阵的乘法计算。

np.inner(a, b)

inner函数要求形参里的第一个矩阵a和形参里的第二个矩阵b的转置$b^T$ 满足矩阵乘法的要求即a的列等于$b^T$的行。

import numpy as np
a = np.arange(1, 7).reshape([2, 3])
b = np.arange(1, 4).reshape([3, 1])
print np.matmul(a, b),"# matmul(a, b)"
print a, "# a"
print b, "# b"
print np.dot(a, b), "# dot(a, b)"
print "*" * 20
print a, "# a"
b = np.arange(1, 4).reshape([1, 3])
print b, "# b"
print np.inner(a, b), "# inner(a, b)"

程序执行结果:

[[14]
 [32]] # matmul(a, b)
[[1 2 3]
 [4 5 6]] # a (2, 3)
[[1]
 [2]
 [3]] # b (3, 1)
[[14]
 [32]] # dot(a, b) => (2, 1)
********************
[[1 2 3]
 [4 5 6]] # a (2, 3)
[[1 2 3]] # b (1, 3)
[[14]
 [32]] # inner(a, b)

注意使用inner的b矩阵的shape是(1, 3)而dot的矩阵b的shape是(3, 1)。

10.1.1 矩阵乘法数学计算过程

1). np.dot(a, b)的数学计算:

2). np.inner(a, b)的数学计算,先将b转置

后续和1)一样计算。

10.2 向量的点积(内积)

对于两个一维数组(向量)dot和inner两个数组的计算是对应元素相乘之和作为计算结果值,数学公式如下所示。

$v = a \bullet b = \sum_{i = 0}^{n - 1} a_i \times b_i$

import numpy as np
a = np.arange(1, 7)
b = np.arange(2, 8)
print a, "# a"
print b, "# b"
print np.dot(a, b), "# dot(a, b)"
print np.inner(a, b), "# inner(a, b)"

程序执行结果:

[1 2 3 4 5 6] # a
[2 3 4 5 6 7] # b
112 # dot(a, b)
112 # inner(a, b)

10.3 inner函数总结

多维矩阵a和b的inner内积等价于第一个矩阵乘第二个矩阵b的转置。

10.4 outer函数外积

在理解了inner之后,outer相当于将形参里的第一个矩阵转置乘形参里的第二个矩阵。

import numpy as np
a = np.arange(1, 5)
b = np.arange(2, 5)
print a, "# a"
print b, "# b"
print np.outer(a, b), "# outer(a, b)"
print "*" * 20
a = np.arange(1, 5).reshape((4, 1))
b = np.arange(2, 5).reshape((1, 3))
print a, "# a"
print b, "# b"
print np.matmul(a, b), "# matmul(a, b)"

程序执行结果:

[1 2 3 4] # a
[2 3 4] # b
[[ 2  3  4]
 [ 4  6  8]
 [ 6  9 12]
 [ 8 12 16]] # outer(a, b)
********************
[[1]
 [2]
 [3]
 [4]] # a
[[2 3 4]] # b
[[ 2  3  4]
 [ 4  6  8]
 [ 6  9 12]
 [ 8 12 16]] # matmul(a, b)

10.4.1 outer的数学计算过程

a、b都是行向量: $$ a = \left| \begin{matrix} 1 & 2 & 3 & 4 \end{matrix} \right| $$

$$ b = \left| \begin{matrix} 2 & 3 & 4 \end{matrix} \right| $$

a的转置为:

np.outer(a, b)外积则是: