对 numpy 数组的许多随机排列进行采样的最快方法

fastest way to sample many random permutations of a numpy array

与许多其他 numpy/random 函数不同,numpy.random.Generator.permutation() 没有提供在单个函数调用中 return 多个结果的明显方法。给定一个 (1d) numpy 数组 x,我想对 xn 排列进行采样(每个长度为 len(x)),并将结果作为形状为 (n, len(x))。生成许多​​排列的一种天真的方法是 np.array([rng.permutation(x) for _ in range(n)])。这并不理想,主要是因为循环在 Python 中而不是在已编译的 numpy 函数中。

import numpy as np

rng = np.random.default_rng(1234)
# x is big enough to not want to enumerate all permutations
x = rng.standard_normal(size=20)
n = 10000
perms = np.array([rng.permutation(x) for _ in range(n)])

我的用例是用于暴力搜索以找到最小化特定 属性 的排列(构成“足够好”的搜索解决方案)。我可以使用 numpy 运算为每个排列计算感兴趣的 属性,vectorise/broadcast 很好地覆盖生成的排列矩阵。事实证明,天真地生成排列矩阵是我代码中的瓶颈。有没有更好的方法?

您可以使用 rng.permuted 代替 rng.permutation 并将其与 np.tile 结合使用,以便多次重复 x 并独立打乱每个副本。方法如下:

perms = rng.permuted(np.tile(x, n).reshape(n,x.size), axis=1)

这在我的机器上比您的初始代码快大约 10 倍。