import numpy as np
a = np.matrix([[1,2,3],[5,5,6],[7,9,9]])
a
matrix([[1, 2, 3],
[5, 5, 6],
[7, 9, 9]])a*a**-1
matrix([[ 1.00000000e+00, 0.00000000e+00, -5.55111512e-17],
[ 4.44089210e-16, 1.00000000e+00, -1.11022302e-16],
[ 4.44089210e-16, 0.00000000e+00, 1.00000000e+00]])因为 a 是用 matrix 创建的矩阵对象,因此乘法和幂运算符都变成了矩阵运算, 于是上面计算的是矩阵a和其逆矩阵的乘积,结果是一个单位矩阵。 矩阵的乘积可以使用 dot 函数进行计算。对于二维数组,它计算的是矩阵乘积,对于一维数组,它计算的是其点积。
当需要将一维数组当作列矢量或者行矢量进行矩阵运算时,推荐先使用 reshape 函数将一维数组转换为二维数组:
a = np.array([1, 2, 3])
a.reshape((-1,1))
array([[1],
[2],
[3]])a.reshape((1,-1))
array([[1, 2, 3]])
dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])
下面以两个3为数组的乘积演示一下 dot 乘积的计算结果:
首先创建两个3维数组,这两个数组的最后两维满足矩阵乘积的条件:
a = np.arange(12).reshape(2,3,2)
b = np.arange(12,24).reshape(2,2,3)
a, b
(array([[[ 0, 1],
[ 2, 3],
[ 4, 5]],
[[ 6, 7],
[ 8, 9],
[10, 11]]]),
array([[[12, 13, 14],
[15, 16, 17]],
[[18, 19, 20],
[21, 22, 23]]]))c = np.dot(a,b)
c
array([[[[ 15, 16, 17],
[ 21, 22, 23]],
[[ 69, 74, 79],
[ 99, 104, 109]],
[[123, 132, 141],
[177, 186, 195]]],
[[[177, 190, 203],
[255, 268, 281]],
[[231, 248, 265],
[333, 350, 367]],
[[285, 306, 327],
[411, 432, 453]]]])dot 乘积的结果c可以看作是数组a,b的多个子矩阵的乘积:
# np.alltrue( c[0,:,0,:] == np.dot(a[0],b[0]) )
np.all( c[0,:,0,:] == np.dot(a[0],b[0]) )
np.True_
# np.alltrue( c[1,:,0,:] == np.dot(a[1],b[0]) )
np.all( c[1,:,0,:] == np.dot(a[1],b[0]) )
np.True_
np.all( c[0,:,1,:] == np.dot(a[0],b[1]) )
np.True_
np.all( c[1,:,1,:] == np.dot(a[1],b[1]) )
np.True_
inner: 和dot乘积一样,对于两个一维数组,计算的是这两个数组对应下标元素的乘积和; 对于多维数组,它计算的结果数组中的每个元素都是:数组a和b的最后一维的内积, 因此数组a和b的最后一维的长度必须相同:
inner(a, b)[i,j,k,m] = sum(a[i,j,:]*b[k,m,:])
下面是 inner 乘积的演示:
a = np.arange(12).reshape(2,3,2)
b = np.arange(12,24).reshape(2,3,2)
c = np.inner(a,b)
c.shape
(2, 3, 2, 3)
c[0,0,0,0] == np.inner(a[0,0],b[0,0])
np.True_
c[0,1,1,0] == np.inner(a[0,1],b[1,0])
np.True_
c[1,2,1,2] == np.inner(a[1,2],b[1,2])
np.True_
outer: 只按照一维数组进行计算,如果传入参数是多维数组,则先将此数组展平为一维数组之后再进行运算。outer乘积计算的列向量和行向量的矩阵乘积:
np.outer([1,2,3],[4,5,6,7])
array([[ 4, 5, 6, 7],
[ 8, 10, 12, 14],
[12, 15, 18, 21]])矩阵中更高级的一些运算可以在NumPy的线性代数子库 linalg 中找到。例如 inv 函数计算逆矩阵, solve 函数可以求解多元一次方程组。下面是 solve 函数的一个例子:
a = np.random.rand(10,10)
b = np.random.rand(10)
x = np.linalg.solve(a,b)
np.sum(np.abs(np.dot(a,x) - b))
np.float64(9.43689570931383e-16)
solve 函数有两个参数a和b。a是一个 N*N 的二维数组,而b是一个长度为N的一维数组, solve 函数找到一个长度为N的一维数组x,使得a和x的矩阵乘积正好等于b,数组x就是多元一次方程组的解。 有关线性代数方面的内容将在今后的章节中详细介绍。