2014-04-09 164 views
2

我有一個3xN陣列,概念上的N 3-矢量陣列,我要建構 陣列從矩陣給定3x3矩陣與 陣列的每一列乘以結果。有沒有一種以矢量化的方式做到這一點的好方法?numpy的:廣播矩陣相乘翻過陣列

目前,我的問題是3xN,但我將來可能需要考慮3xNxM(或更多)。

糊塗的做法

U=numpy.rand([3,24]) 

R=numpy.eye(3) # placeholder 

for i in xrange(U.shape[1]): 
    U[:,i]=numpy.dot(R, U[:,i]) 
+0

在這裏看到我的答案:http://stackoverflow.com/a/22081723/553404 – YXD

+0

@MrE的答案是相當不錯的,對於我的形狀(3xN),我避免了你在那裏提到的轉置。 – Dave

回答

4

使用np.einsum函數,即使對於多di大小問題:

U = np.random.rand(3,24,5) 
R = np.eye(3,3) 
result = np.einsum("ijk,il", U,R) 

該符號有點棘手:您首先給出的字符串指出了數組維度的單元;所以對於U而言,ijk是每個維度的運行餘量。它遵循愛因斯坦求和慣例,所以在字符串中具有相同字母的元素將被求和。詳情請參閱ScipyDocs。我敢肯定在你的情況下,點更快,因爲開銷更少,它可能會使用一些例程,但正如你所說,你想擴展到更多維度,這可能是一條路。

+2

在實際的基準測試中,Einsum經常拉開序幕。特別是在這些涉及小尺寸收縮的情況下。我想通過gufunc機制來調用BLAS;也就是說,每個微小的子矩陣都有一個單獨的BLAS調用。在這樣的情況下,BLAS會因O(N)的開銷而受到影響,這會很快壓倒Einsum的O(1)開銷。 –

3

在這種情況下,你可以簡單地調用np.dot(R, U),它會工作:

import numpy as np 

np.random.seed(0) 

U = np.random.rand(3,24) 
R = np.random.rand(3,3) 

result = np.empty_like(U) 

for i in range(U.shape[1]): 
    result[:,i] = np.dot(R, U[:,i]) 

print result 

print np.allclose(result, np.dot(R, U)) 

對於(3xNxM)情況下,你可以重塑到(3次(NM)),dot和重塑結果回來,類似於我的回答here

+0

我認爲使用np.dot時,可以實際上是要走的路,因爲它經常使用真正快速的庫,如Blas或Lapack進行了高度優化。 – Magellan88