如何解决从python生成器中抽取随机样本
我正在使用函数for pair in itertools.combinations(bug_map.keys(),2):
在数据库中生成所有成对的元素。问题在于元素的数量约为6.6 K,因此组合的数量为21.7M。而且,组合是按词典编排顺序发出的。
假设我会从生成器中获取随机对,而不会“收获”所有对(只是n维的子集),我该怎么办?
解决方法
如果允许您将所有6K
元素作为列表来获取,则首先获取所有元素,然后使用标准python的random.choices()
生成一批具有替换的样品。然后应用排序(对组合进行排序)。然后删除两次或多次内具有相同元素的元组以及相等的元组。重复批处理生成,直到获得足够的n
个元组。
您可以在我的代码中将任何k
指定为要生成的所需元组的长度,并将n
指定为要生成的k长度元组的数量。
此算法生成与创建k
个长度的所有组合然后选择大小为n
的随机子集相似的概率分布模式。
import random
#random.seed(0) # Do this only for testing to have reproducible random results
l = list(range(1000,1000 + 6600)) # Example list of all input elements
k = 2 # Length of each tuple to generate
n = 30 # Number of tuples to generate
batch = max(1,n // 4) # Number of k-tuples to sample at once
maybe_sort = lambda x: sorted(x) if is_sorted else x
res = []
while True:
if len(res) >= n:
res = res[:n]
break
a = random.choices(range(len(l)),k = k * batch) # Generate random samples from inputs with replacement
a = sorted(res + [tuple(sorted(a[i * k + j] for j in range(k))) for i in range(batch)])
res = [a[0]]
for e in a[1:]:
if all(e0 != e1 for e0,e1 in zip(e[:-1],e[1:])) and res[-1] != e:
res.append(e)
print([tuple(l[i] for i in tup) for tup in res])
,
这似乎是微不足道的,但是如果所需的样本数量远小于可能的组合总数(21.8 M),则可以重复生成ramdom.sample
,直到有足够的数量为止。可能会发生冲突,但是(同样,如果所需的样本数量相对较少),发生冲突的可能性可以忽略不计,并且不会导致速度降低。
import random
lst = range(6000)
n = 1000000
k = 2
samples = set()
while len(samples) < n:
samples.add(tuple(random.sample(lst,k)))
即使对于1,000,000个随机样本,也仅产生约12,000次碰撞,即“浪费”迭代的大约1%,这可能不是什么大问题。
请注意,除了combinations
之外,ramdom.sample
返回的对没有排序(第一个元素可以大于第二个元素),因此您可能要使用tuple(sorted(...))
>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。