无替换样本的 np.random.choice 与 np.random.shuffle 的比较

Rit*_*wik 5 python arrays random numpy shuffle

我的用例有点具体。我想从列表/数组(50 或 100 个元素)中采样 2 个项目而不替换。所以我不必担心大小为 10^4 或 10^5 的数组或多维数据。

我想知道

  1. 哪个,numpy.random.choice()或者numpy.random.shuffle()为此目的更快,为什么?
  2. 如果他们都产生“质量好”的随机样本?也就是说,两者都是为我的目的生成好的随机样本,还是产生较少的随机样本?(只是一个健全性检查,以确保我没有忽略有关这些函数的源代码的内容)。

对于问题 1,我尝试对两个函数进行计时(下面的代码),shuffle 方法似乎快了 5-6 倍。非常欢迎您对此提供任何见解。如果有更快的方法来实现我的目的,我会很高兴听到它们(我已经查看了 pythonrandom模块的选项,但我测试中最快的方法是使用np.random.shuffle())。

def shuffler(size, num_samples):
    items = list(range(size))
    np.random.shuffle(items)
    return items[:num_samples]
    
def chooser(size, num_samples):
    return np.random.choice(size, num_samples, replace=False)

%timeit shuffler(50, 2)
#> 1.84 µs ± 17.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit chooser(50, 2)
#> 13 µs ± 1.09 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Run Code Online (Sandbox Code Playgroud)

您可能认为它已经优化了,而我正在浪费时间试图节省便士。但是np.random.choice()在我的代码中被调用了 5000000 次并且占用了我大约 8% 的运行时间。它在循环中用于每次迭代从总体中获取 2 个随机样本。伪代码:

for t in range(5000000):
    # Random sample of 2 from the population without replacement.
Run Code Online (Sandbox Code Playgroud)

如果我的要求有更智能的实现,我愿意接受建议。

PS:我知道shuffle执行就地操作,但因为我只需要两个随机元素的索引,所以我基本上不必在我的原始数组上执行它。还有其他问题可以比较 pythonrandom模块中的两个函数。但我需要 2 个样品而无需更换。

Pet*_* O. 2

请参阅源代码numpy.random.choice;它replace=False会创建一个包含 50 项的临时列表,对该列表进行洗牌,然后从该列表中取出两项。

numpy.random.choice自版本 1.17 以来,与numpy.random.shuffle其他函数一样numpy.random,在不影响向后兼容性的情况下无法更改 和 的实现决策(请参阅NumPy 的最新 RNG 政策)。另请参阅以下问题:

numpy.random.choice与进行比较numpy.random.Generator.choice,这是 NumPy 1.17 及更高版本中对项目进行采样的较新方法。优点是numpy.random.Generator.choice不受与numpy.random.choice或相同的兼容性保证numpy.random.shuffle。如果您关心性能,numpy.random.Generator可以在 NumPy 的 GitHub 存储库中提出问题。