内置 range 或 numpy.arange: 哪个更有效?

当使用范围表达式迭代一个大型数组时,我应该使用 Python 的内置 range函数还是 numpy 的 arange来获得最佳性能?

到目前为止,我的理由是:

range可能采用本机实现,因此可能更快。另一方面,arange返回一个完整的数组,它占用内存,因此可能会有开销。Python3的范围表达式是一个生成器,它不包含内存中的所有值。

79917 次浏览

首先,由@bmu,你应该使用向量计算,ufuns 和索引的组合编写。确实有一些情况需要显式循环,但这种情况真的很少见。

如果需要显式的循环,使用 python 2.6和2.7,应该使用 Xrange(参见下面)。根据您所说的,在 Python3中,射程Xrange(返回一个生成器)相同。所以也许 射程对你也有好处。

你应该自己试试 (使用 timeit:-here the ipython“ magic function”) :

%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: 快多了。这就是我们所说的“矢量编程”。它使程序比 C 语言更容易实现(也更具可读性) ,但最终速度几乎和 C 语言一样快。

对于大型数组,向量化的数运算是最快的。如果必须循环,请选择 xrange/range,避免使用 np.arange

在麻木,你应该使用矢量计算,Ufuns索引的组合来解决你的问题,因为它运行在 C的速度。 与此相比,在数字数组上循环是低效的。

(就像你问题的第一句话建议的那样,你可能做的最糟糕的事情就是用用 rangenp.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倍。根据您的问题麻木可以更快比4或5倍的速度。

这个问题的答案解释了对大型数据集使用 numpy 数组而不是 python 列表的一些更多优点。