Python:给定一组N个元素,随机选择k,m次

时间:2018-02-02 10:10:56

标签: python permutation

给定一组N个元素,我想选择k个元素的m个随机,非重复子集。

如果我想要生成全部,N选择k组合,我可以 使用itertools.combination,所以我要问的一种方法是:

import numpy as np
import itertools
n=10
A = np.arange(n)
k=4
m=5
result = np.random.permutation([x for x in itertools.permutations(A,k)])[:m]
print(result)

问题当然是这段代码首先生成全部可能的排列,而且这可能非常昂贵。

另一个次优解决方案是每次随机选择一个排列(e.g. choose-at-random-from-combinations,然后排序以获得排列),如果已经选择了它,则将其丢弃。

有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

最简单的方法是random.shuffle(range)然后获取前k个元素(需要重复,直到收集到m个有效样本)。

当然这个程序不能保证独特的样品。如果确实需要,您将根据历史哈希检查新样本。

自Pyton2.3起,random.sample(range, k)可用于以更有效的方式生成样本

答案 1 :(得分:1)

您的第二个解决方案似乎是唯一可行的方法。除非k接近n而m是"大"否则它会很好地工作。在这种情况下会有更多的重复。

我添加了获取所需样本所需的尝试次数。对于m = 50,n = 10且k = 4,通常需要少于60次尝试。您可以看到它与人口和样本的大小有关。

您可以使用random.sample获取k值列表而无需替换,然后对其进行排序并将其转换为元组。因此,我们可以使用set来保留唯一的结果。

import random

n = 10
A = list(range(n))
k = 4
m = 5

samples = set()
tries = 0
while len(samples) < m:
    samples.add(tuple(sorted(random.sample(A, k))))
    tries += 1

print(samples)
print(tries)

# {(1, 4, 5, 9), (0, 3, 6, 8), (0, 4, 7, 8), (3, 5, 7, 9), (1, 2, 3, 4)}
# 6
# 6 tries this time !