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

Posted

技术标签:

【中文标题】内置范围或 numpy.arange:哪个更有效?【英文标题】:built-in range or numpy.arange: which is more efficient? 【发布时间】:2012-05-28 18:09:44 【问题描述】:

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

到目前为止我的推理:

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

【问题讨论】:

arange 可能诉诸 ==> range 可能诉诸。好像是笔误。 【参考方案1】:

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

如果需要显式循环,对于 python 2.6 和 2.7,您应该使用 xrange(见下文)。根据您的说法,在 Python 3 中,rangexrange 相同(返回一个生成器)。所以也许 range 对你也一样好。

现在,您应该自己尝试一下 (使用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

同样,如上所述,大多数时候可以使用运行 c 速度的 numpy 向量/数组公式(或 ufunc 等):快得多。这就是我们所说的“向量编程”。它使程序比 C 更容易实现(并且更具可读性),但最终几乎一样快。

【讨论】:

有一个标准的 python 'timeit' 模块允许在没有 IPython 的情况下做同样的事情。但是使用这个神奇的功能要容易得多。 我完全同意,但问题是关于“迭代一个大数组”。在某些情况下,无法使用 numpy 矢量化、ufunc 或索引。我遇到的一个例子是计算矩阵列表的特征向量 (>= 3x3) 我不知道 np.arange 自 2012 年以来是否变得更有效率,但与内置的 range 相比,它的主要兴趣在于您可以使用浮点数作为开始:停止:步骤。 np.arange 在我们有非整数步长时很有用【参考方案2】:

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

在 numpy 中,您应该使用矢量化计算的组合,ufuncs 和 indexing 来解决您的问题,因为它以 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 列表的更多优势。

【讨论】:

值得一提的是,Python3.x中没有xrangerangexrange是一样的。 另外,我测试了for x in np.arange(size): x ** 2,它比numpy==1.16.4python 3.6中的for x in range(size): x ** 2

以上是关于内置范围或 numpy.arange:哪个更有效?的主要内容,如果未能解决你的问题,请参考以下文章

对于一个或两个字符的字符串,哪个更有效:CHAR(2) 或 VARCHAR(2)?

哪个更有效,基本互斥锁或原子整数?

如何计算 2D numpy 数组的所有列的总和(有效)

使用 #pragma once 或 #ifndef #endif 哪个更有效?

使用 spark 版本 2 在 HIVE 中哪个更有效,最大或按 desc 限制 1 排序

python range函数与numpy arange函数