无需替换即可生成置换数组

Generating permutation array without replacement

我正在尝试获取大小为 (1000, 7) 的矩阵,其中每一行都是数字 0 到 6 的随机排列。 我正在使用以下代码来实现需求。

import numpy as np

permute_array = []
for i in range(1000):
    permute_array.append(np.random.permutation(7))
permute_array = np.array(permute_array)

这很慢,因为 for 循环需要相当长的时间才能完成 运行。是否有生成此数组的一次性方法?谢谢

也许您可以使用 itertools.permutations 生成所有排列(在您的情况下为 5040),然后随机使用 random.choices 到 select 1000 个排列。 它将避免有两个相同的行,而您的代码不能。不知道会不会快点。

您可以从零开始创建一个数组,然后用排列替换它,使用来自 np 的 apply_along_axis 非常快。

import itertools

np.apply_along_axis(lambda _: list(itertools.permutations(range(7))), 0, np.zeros(1000))

有几种方法可以做到这一点, 如果您只需要针对这种情况(此函数)的解决方案,您只需创建数组 (1000,7) 用范围 (7) 填充它,然后使用 np.apply_along_axis:

随机排列每一行

(不推荐用于抽象解决方案,但它确实很快)

import numpy as np
a = np.full((1000, 7),fill_value=np.arange(7))
np.apply_along_axis(func1d=np.random.shuffle, axis=1, arr=a)
print(a[:5])

性能:每个循环 2.96 毫秒 ± 21.9 微秒(7 次运行的平均值 ± 标准差,每次 100 次循环)

另一个优雅且快速且更抽象的解决方案是使用您的排列函数:

import numpy as np
a = np.array([np.random.permutation(7) for i in range(1000)])
print(a[:5])

性能:每个循环 2.13 毫秒 ± 30.8 微秒(7 次运行的平均值 ± 标准偏差,每次 100 次循环)

第二个解决方案看起来有点快。

import numpy as np
permute_array = np.argsort(np.random.rand(1000, 7), axis=1)