2015-01-21 111 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 
相關問題