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就是多元一次方程组的解。
有关线性代数方面的内容将在今后的章节中详细介绍。