當使用範圍表達式對一個大型數組進行迭代時,是否應該使用Python的內置範圍函數或numpy的arange
以獲得最佳性能?內置範圍或numpy.arange:哪個效率更高?
我到目前爲止的推理:
arange
可能訴諸於本地實現,並且可能會更快,因此,另一方面,arange
返回一個完整的數組,佔用內存,所以可能會有開銷。 Python 3的範圍表達式是一個生成器,它並不包含內存中的所有值。
當使用範圍表達式對一個大型數組進行迭代時,是否應該使用Python的內置範圍函數或numpy的arange
以獲得最佳性能?內置範圍或numpy.arange:哪個效率更高?
我到目前爲止的推理:
arange
可能訴諸於本地實現,並且可能會更快,因此,另一方面,arange
返回一個完整的數組,佔用內存,所以可能會有開銷。 Python 3的範圍表達式是一個生成器,它並不包含內存中的所有值。
對於大型數組,numpy應該是更快的解決方案。
在numpy中,您應該使用矢量化計算組合ufuncs和indexing解決您的問題,因爲它運行在C
速度。 與此相比,循環播放numpy數組效率低下。你可以做的最糟糕的事情就是遍歷整個數組,其索引創建時使用range
或np.arange
作爲你問題的第一句話,但我不確定你是否真的這麼認爲。)
import numpy as np
import sys
sys.version
# out: '2.7.3rc2 (default, Mar 22 2012, 04:35:15) \n[GCC 4.6.3]'
np.version.version
# out: '1.6.2'
size = int(1E6)
%timeit for x in range(size): x ** 2
# out: 10 loops, best of 3: 136 ms per loop
%timeit for x in xrange(size): x ** 2
# out: 10 loops, best of 3: 88.9 ms per loop
# avoid this
%timeit for x in np.arange(size): x ** 2
#out: 1 loops, best of 3: 1.16 s per loop
# use this
%timeit np.arange(size) ** 2
#out: 100 loops, best of 3: 19.5 ms per loop
因此,對於這種情況下numpy的比使用xrange
如果你這樣做是正確的快4倍。取決於你的問題,numpy比4倍或5倍加速要快得多。
this question的答案解釋了使用numpy數組代替python列表的大數據集的更多優點。
首先,如@bmu,所寫,您應該使用向量化計算的組合,ufuncs和索引。確實存在一些需要顯式循環的情況,但這些情況非常罕見。
如果需要顯式循環,使用python 2.6和2.7,你應該使用xrange(見下文)。從你說的,在Python 3中,範圍與xrange(返回一個發生器)相同。所以也許範圍對你很好。
現在,你應該嘗試一下自己 (使用timeit: - 這裏的IPython的「神奇功能」):
%timeit for i in range(1000000): pass
[out] 10 loops, best of 3: 63.6 ms per loop
%timeit for i in np.arange(1000000): pass
[out] 10 loops, best of 3: 158 ms per loop
%timeit for i in xrange(1000000): pass
[out] 10 loops, best of 3: 23.4 ms per loop
此外,如上文提到的,大多數的時候,可以使用numpy的矢量/數組公式(或ufunc等)運行交流速度:快得多。這就是我們所說的「矢量編程」。它使程序比C更容易實現(並且更易讀),但最終速度幾乎一樣快。
謝謝,我不知道魔術功能。 – clstaudt
有一個標準的python'timeit'模塊,它允許在沒有IPython的情況下執行相同的操作。但是使用這個神奇功能要容易得多。 –
-1因爲我認爲這不是一個好的基準。循環遍歷一個numpy數組效率不高。 – bmu