[英]Element-wise effecient multiplication of arrays of matrices
假設array_1
和array_2
是兩個大小相同的矩陣數組。 是否有任何向量化的方式將這兩個數組的元素逐元素相乘(它們的元素相乘定義明確)?
偽代碼:
def mat_multiply(array_1,array_2):
size=np.shape(array_1)[0]
result=np.array([])
for i in range(size):
result=np.append(result,np.dot(array_1[i],array_2[i]),axis=0)
return np.reshape(result,(size,2))
輸入示例:
a=[[[1,2],[3,4]],[[1,2],[3,4]]]
b=[[1,3],[4,5]]
輸出:
[[ 7. 15.]
[ 14. 32.]]
與您的第一句話相反, a
和b
的大小不同。 但是,讓我們關注您的示例。
所以你想要這個-2點積, a
和b
每一行a
np.array([np.dot(x,y) for x,y in zip(a,b)])
或避免附加
X = np.zeros((2,2))
for i in range(2):
X[i,...] = np.dot(a[i],b[i])
dot
積可以用einsum
(矩陣索引符號)表示為
[np.einsum('ij,j->i',x,y) for x,y in zip(a,b)]
所以下一步就是索引第一個維度:
np.einsum('kij,kj->ki',a,b)
我對einsum
相當熟悉,但是要弄清楚您想要什么仍然需要反復試驗。 現在問題已經很清楚了,我可以用其他幾種方式來計算它
A, B = np.array(a), np.array(b)
np.multiply(A,B[:,np.newaxis,:]).sum(axis=2)
(A*B[:,None,:]).sum(2)
np.dot(A,B.T)[0,...]
np.tensordot(b,a,(-1,-1))[:,0,:]
我發現使用具有不同大小的數組會有所幫助。 例如,如果A
為(2,3,4)
而B
(2,4)
,則很明顯點總和必須位於最后一個維度上。
另一個numpy迭代工具是np.nditer
。 einsum
使用它(在C中)。 http://docs.scipy.org/doc/numpy/reference/arrays.nditer.html
it = np.nditer([A, B, None],flags=['external_loop'],
op_axes=[[0,1,2], [0,-1,1], None])
for x,y,w in it:
# x, y are shape (2,)
w[...] = np.dot(x,y)
it.operands[2][...,0]
避免執行[...,0]
步驟,需要進行更詳細的設置。
C = np.zeros((2,2))
it = np.nditer([A, B, C],flags=['external_loop','reduce_ok'],
op_axes=[[0,1,2], [0,-1,1], [0,1,-1]],
op_flags=[['readonly'],['readonly'],['readwrite']])
for x,y,w in it:
w[...] = np.dot(x,y)
# w[...] += x*y
print C
# array([[ 7., 15.],[ 14., 32.]])
@hpaulj在他廣泛而全面的選項列表中遺漏了另一個選項:
>>> a = np.array(a)
>>> b = np.array(b)
>>> from numpy.core.umath_tests import matrix_multiply
>>> matrix_multiply.signature
'(m,n),(n,p)->(m,p)'
>>> matrix_multiply(a, b[..., np.newaxis])
array([[[ 7],
[15]],
[[14],
[32]]])
>>> matrix_multiply(a, b[..., np.newaxis]).shape
(2L, 2L, 1L)
>>> np.squeeze(matrix_multiply(a, b[..., np.newaxis]), axis=-1)
array([[ 7, 15],
[14, 32]])
關於matrix_multiply
的好處是,它是gufunc,它不僅適用於矩陣的一維數組,而且還適用於可廣播的數組。 例如,如果要計算所有可能的乘法運算,而不是將第一個矩陣與第一個向量相乘,而將第二個矩陣與第二個向量相乘,則可以執行以下操作:
>>> a = np.arange(8).reshape(2, 2, 2) # to have different matrices
>>> np.squeeze(matrix_multiply(a[...,np.newaxis, :, :],
... b[..., np.newaxis]), axis=-1)
array([[[ 3, 11],
[ 5, 23]],
[[19, 27],
[41, 59]]])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.