對向量陣列的矩陣運算
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.])