为什么random.choices比NumPy的随机选择更快?

5

我正在尝试以最高效的方式在Python中进行随机抽样,但我感到困惑,因为使用numpy的random.choices()比使用random.choices()要慢。

import numpy as np
import random

np.random.seed(12345)

# use gamma distribution
shape, scale = 2.0, 2.0 
s = np.random.gamma(shape, scale, 1000000)
meansample = []

samplesize = 500

%timeit meansample = [ np.mean( np.random.choice( s, samplesize, replace=False)) for _ in range(500)]
23.3 s ± 229 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit meansample = [np.mean(random.choices(s, k=samplesize)) for x in range(0,500)]
152 ms ± 324 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

23秒与152毫秒的时间差很大

我做错了什么?


random.choices 允许重复,而 np.random.choice( ..., replace=False) 则不允许。 - Divakar
@Divakar 可能是 OP 打错了,但 np.random.choice 有更好的无重复元素的替代方案。 - hilberts_drinking_problem
@hilberts_drinking_problem 我们在谈论什么替代方案?好吧,OP正在询问replace=False的情况,这比random.choices慢,但这是两个不同的事情。而对于replace=True,它与random.choices相同且更快。因此,在比较类似功能时,这个问题并不成立。 - Divakar
@Divakar 我同意 random.choices 可能应该是 random.sample。然而,random.sample 在不重复的情况下表现更好,如果使用 np.random.Generator.choice 而不是 np.random.choice,则 numpy 的速度会更快。 - hilberts_drinking_problem
1个回答

5

这里有两个问题。首先,对于纯Python的random库,您可能想使用sample而不是choices进行无重复抽样。这会略微改变基准测试结果。其次,np.random.choice在进行无重复抽样时有更好的性能替代方案。这是与随机生成器API相关的已知问题。您可以使用np.random.Generator以获得更好的性能。我的时间记录如下:

%timeit meansample = [ np.mean( np.random.choice( s, samplesize, replace=False)) for _ in range(500)]
# 1 loop, best of 3: 12.4 s per loop

%timeit meansample = [np.mean(random.choices(s, k=samplesize)) for x in range(0,500)]
# 10 loops, best of 3: 118 ms per loop

sl = s.tolist()
%timeit meansample = [np.mean(random.sample(sl, k=samplesize)) for x in range(0,500)]
# 1 loop, best of 3: 219 ms per loop

g = np.random.Generator(np.random.PCG64())
%timeit meansample = [ np.mean( g.choice( s, samplesize, replace=False)) for _ in range(500)]
# 10 loops, best of 3: 25 ms per loop

因此,在不进行替换的情况下,random.sample 的性能优于 np.random.choice,但比 np.random.Generator.choice 慢。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接