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

v8wbuo2f  于 2023-02-23  发布在  其他
关注(0)|答案(3)|浏览(123)

当使用range表达式迭代一个大数组时,应该使用Python内置的range函数还是numpy的arange函数来获得最佳性能?
我目前的推理是:
range可能会采用本机实现,因此可能会更快。另一方面,arange返回一个完整的数组,这会占用内存,因此可能会有开销。Python 3的range表达式是一个生成器,它不会在内存中保存所有的值。

syqv5f0l

syqv5f0l1#

对于大型数组,向量化numpy操作是最快的。如果必须循环,请首选xrange/range,避免使用np.arange
在numpy中,你应该使用矢量化计算ufuncsindexing的组合来解决你的问题,因为它以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倍。根据你的问题,numpy可以比4或5倍的速度快得多。
this question的答案解释了对于大型数据集使用numpy数组而不是python列表的更多优点。

rkttyhzu

rkttyhzu2#

首先,正如@bmu所写的,* 您应该使用向量化计算、ufuncs和索引的组合 *。确实有一些情况需要显式循环,但这种情况非常罕见。
如果需要显式循环,那么在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

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

osh3o9ms

osh3o9ms3#

这取决于:对于较小的范围,Python的range(...)速度更快,然而,numpynp.arange(...)伸缩性很好,在较大的范围内表现更好:

请查找基准测试代码here。在MacBook Pro M1上运行Python 3.11和numpy 1.23.5
这个问题是从性能的Angular 出发的(这是完全正确的)。然而,我发现可用性/可维护性的Angular 同样重要:导入numpy来创建一个范围是很糟糕的,反之亦然:使用range的大量numpy驱动的代码感觉不对。
还要记住,np.arange对非整数步长有更好的支持。

相关问题