对向量数组的矩阵运算
numpy.dot 可用于通过矩阵乘以向量列表,但向量的方向必须是垂直的,以便八个两个分量向量的列表看起来像两个八个分量向量:
>>> a
array([[ 1., 2.],
[ 3., 1.]])
>>> b
array([[ 1., 2., 3., 4., 5., 6., 7., 8.],
[ 9., 10., 11., 12., 13., 14., 15., 16.]])
>>> np.dot(a, b)
array([[ 19., 22., 25., 28., 31., 34., 37., 40.],
[ 12., 16., 20., 24., 28., 32., 36., 40.]])
如果向量列表的布局与其轴相反(通常是这种情况)那么数组需要在点操作之前和之后进行转置,如下所示:
>>> b
array([[ 1., 9.],
[ 2., 10.],
[ 3., 11.],
[ 4., 12.],
[ 5., 13.],
[ 6., 14.],
[ 7., 15.],
[ 8., 16.]])
>>> np.dot(a, b.T).T
array([[ 19., 12.],
[ 22., 16.],
[ 25., 20.],
[ 28., 24.],
[ 31., 28.],
[ 34., 32.],
[ 37., 36.],
[ 40., 40.]])
尽管点功能非常快,但有时最好使用 einsum。相当于上述内容将是:
>>> np.einsum('...ij,...j', a, b)
这有点慢,但允许顶点列表乘以相应的矩阵列表。这将是一个非常复杂的使用点的过程:
>>> a
array([[[ 0, 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]]])
>>> np.einsum('...ij,...j', a, b)
array([[ 9., 29.],
[ 58., 82.],
[ 123., 151.],
[ 204., 236.],
[ 301., 337.],
[ 414., 454.],
[ 543., 587.],
[ 688., 736.]])
numpy.dot 可用于在列表中找到每个向量的点积,在另一个列表中具有相应的向量,与沿着最后一个轴的逐元素乘法和求和相比,这是非常混乱和缓慢的。像这样的东西(需要一个更大的数组来计算,但大多数被忽略)
>>> np.diag(np.dot(b,b.T))
array([ 82., 104., 130., 160., 194., 232., 274., 320.])
使用逐元素乘法和求和的点积
>>> (b * b).sum(axis=-1)
array([ 82., 104., 130., 160., 194., 232., 274., 320.])
使用 einsum 可以实现
>>> np.einsum('...j,...j', b, b)
array([ 82., 104., 130., 160., 194., 232., 274., 320.])