2015-01-21 44 views
5

考虑下面两个函数,它们将小序列中的每个数与大序列中的每个数乘以构成一个二维数组,然后将所有数值加倍阵列。 noloop()使用2D numpy数组的直接乘法并返回结果,而loop()使用for循环遍历arr1并逐渐建立输出数组。为什么for循环比二维数组乘法更快numpy

import numpy as np 

arr1 = np.random.rand(100, 1) 
arr2 = np.random.rand(1, 100000) 

def noloop(): 
    return (arr1*arr2)*2 

def loop(): 
    out = np.empty((arr1.size, arr2.size)) 
    for i in range(arr1.size): 
     tmp = (arr1[i]*arr2)*2 
     out[i] = tmp.reshape(tmp.size) 
    return out 

我预计noloop是,即使是少量的迭代更快,但对于阵列上方大小,loop实际上更快:

>>> %timeit noloop() 
10 loops, best of 3: 64.7 ms per loop 
>>> %timeit loop() 
10 loops, best of 3: 41.6 ms per loop 

有趣的是,如果我在这两个删除*2功能,noloop比较快,但幅度不大:

>>> %timeit noloop() 
10 loops, best of 3: 29.4 ms per loop 
>>> %timeit loop() 
10 loops, best of 3: 34.4 ms per loop 

是否有个很好的解释这些结果,是否有一种更快的方式来执行相同的任务?

+2

我得到'noloop()'不是'循环速度更快(由〜15%)()'不管...... – 2015-01-21 11:10:48

+0

我也得到了逆转python2和python3。 – 2015-01-21 11:26:19

+1

根据OP的建议,我得到'loop'的速度更快(在我的机器中减少了28%)。 Python 3.4.1 | Anaconda 2.1.0,IPython 2.2.0 – Roberto 2015-01-21 11:37:30

回答

0

我无法重现您的结果,但我确实发现使用numpy.multiply可以大大提高速度(因子2)。通过使用out参数,您可以利用内存已分配的事实并消除tmpout的复制。

def out_loop(): 
    out = np.empty((arr1.size, arr2.size)) 
    for i in range(arr1.size): 
     np.multiply(arr1[i], arr2, out=out[i].reshape((1, arr2.size))) 
     out[i] *= 2 
    return out 

我的机器上结果:

In [32]: %timeit out_loop() 
100 loops, best of 3: 17.7 ms per loop 

In [33]: %timeit loop() 
10 loops, best of 3: 28.3 ms per loop 
相关问题