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

cls*_*udt 55 python numpy range python-3.x

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

我的推理到目前为止:

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

bmu*_*bmu 63

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

在numpy中你应该使用矢量化计算,ufuncs索引的组合来解决你的问题,因为它运行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
Run Code Online (Sandbox Code Playgroud)

因此,对于这种情况,numpy比使用xrange它时快4倍.根据您的问题,numpy可以比加速4或5倍快得多.

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


Juh*_*uh_ 10

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

如果需要显式循环,使用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
Run Code Online (Sandbox Code Playgroud)

同样,如上所述,大多数时候可以使用运行交流速度的numpy向量/数组公式(或ufunc等...):更快.这就是我们所谓的"矢量编程".它使程序比C(更易读)更容易实现,但最终几乎同样快.

  • 有一个标准的python'timeit'模块,它允许在没有IPython的情况下执行相同的操作.但是使用这个神奇的功能要容易得多. (3认同)
  • 我不知道自 2012 年以来 `np.arange` 是否变得更高效,但与内置 `range` 相比,它的主要兴趣在于您可以使用浮点数作为 start:stop:step。 (2认同)
  • 当我们有非整数步长时 np.arange 很有用 (2认同)