對向量陣列的矩陣運算

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.])