2013-10-16 121 views
4

嗨,我正在運行使用numpy + numba的科學計算。 我已經意識到numpy的陣列除了就地很慢......相比MATLABNumpy切片慢?

這裏是MATLAB代碼:

tic; 
% A,B are 2-d matrices, ind may not be distinct 
for ii=1:N 
    A(ind(ii),:) = A(ind(ii),:) + B(ii,:); 
end 
toc; 

這裏是numpy的代碼:

s = time.time() 
# A,B are numpy.ndarray, ind may not be distinct 
for k in xrange(N): 
    A[ind[k],:] += B[k,:]; 
print time.time() - s 

結果顯示,numpy代碼比matlab慢10倍......這讓我很困惑。另外,當我把for循環添加出來,並且比較單個矩陣加法和numpy.add,numpy和matlab似乎在速度上是可比的。

我知道的一個因素是,matlab使用版本大於等於2012a的JIT來加速循環,但是我試圖在Python代碼上使用numba,它仍然無法加速。我認爲這與Numba完全沒有觸及numpy.add函數有關,因此性能根本不會改變。

我猜測matlab爲這種情況做了一些噁心的緩存,因此它戲劇性地大幅度增加了numpy。

任何有關如何加快numpy的建議?

+2

請添加樣本輸入數據'A','B'和'ind'。您可以通過生成正確形狀的隨機數據來做到這一點。沒有這個,回答你的問題主要是猜測。 – YXD

回答

3

嘗試

A[ind] += B[:N] 

即沒有任何迴路。

如果ind可能有重複的元素,你可以使用np.add.at:使用點矩陣乘法

np.add.at(A, ind, B[:N]) 
+2

謝謝,但ind中的元素並不鮮明。 If ind = [1,2,4,1,2]; 比你的代碼實際上對for循環的版本產生不同的結果。 – Jing

+2

好點。我沒有發現。此示例在[文檔](http://wiki.scipy.org/Tentative_NumPy_Tutorial#head-0dffc419afa7d77d51062d40d2d84143db8216c2)中提到,將會考慮可以做什麼 – YXD

+0

請向您的文章添加數據,並且人們將能夠提供幫助更多。否則請參閱Robert Kern建議的方法:http://numpy-discussion.10968.n7.nabble.com/Incrementing-with-advanced-indexing-why-don-t-repeated-indexes-repeatedly-increment-td26288.html – YXD

0

Here'a版本。它從ind構建1和0的矩陣。

def bar(A,B,ind): 
    K,M =B.shape 
    N,M =A.shape 
    I = np.zeros((N,K)) 
    I[ind,np.arange(K)] = 1 
    return A+np.dot(I,B) 

對於大小問題像K,M,N = 30,14,15這是大約3倍速度更快。但對於像K,M,N = 300,100,150這樣的較大型號來說,速度有點慢。