2013-10-16 74 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这样的较大型号来说,速度有点慢。