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

时间:2012-05-22 09:02:06

标签: python numpy python-3.x range

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

到目前为止我的理由:

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

2 个答案:

答案 0 :(得分:56)

对于大型阵列,numpy应该是更快的解决方案。

在numpy中,您应该使用矢量化计算的组合ufuncsindexing来解决问题,因为它以C速度运行。 与此相比,在numpy数组上循环效率低下。

(你可以做的最糟糕的事情就是使用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倍。根据您的问题,numpy可以比加速4或5倍快得多。

this question的答案解释了为大型数据集使用numpy数组而不是python列表的更多优点。

答案 1 :(得分:10)

首先,正如@bmu所写,你应该使用矢量化计算,ufuncs和索引的组合。确实有些情况需要显式循环,但这些很少见。

如果需要显式循环,使用python 2.6和2.7,则应使用 xrange (见下文)。根据你的说法,在Python 3中, range 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 vector / array formula(或ufunc etc ...)来运行c速度:快得多。这就是我们可以称之为"矢量编程"。它使程序比C更容易实现(更易读),但最终几乎同样快。