我想将m*n
元素(例如,1,2,…,m*n
(随机均匀地划分为n
组,使得每组都有m
随机元素。每个组将一次处理来自其自己组的k
(k>=1
(元素,并以相同的速度(通过某种同步机制(处理,直到所有组都处理了其自己的所有元素。实际上,每个组都在一个独立的进程/线程中。
我使用numpy.random.choice(m*n, m*n, replace=False)
首先生成排列,然后对每组的排列结果进行索引。
问题是,当m*n
非常大(例如>=1e8
(时,速度非常慢(几十秒或几十分钟(。
有什么更快/更懒的方法可以做到这一点吗?我想也许这可以用一种更懒惰的方式来完成,即不是第一次生成排列结果,而是先生成一个生成器,在每组中,每次生成k个元素,其效果应该与我目前使用的方法相同。但我不知道如何实现这种懒惰的方式。我不确定这是否真的可以实施。
您可以制作一个生成器,它将逐步打乱列表(的副本(,并惰性地生成不同的组:
import random
def rndGroups(A,size):
A = A.copy() # work on a copy (if needed)
p = len(A) # target position of random item
for _ in range(0,len(A),size): # work in chunks of group size
for _ in range(size): # Create one group
i = random.randrange(p) # random index in remaining items
p -= 1 # update randomized position
A[i],A[p] = A[p],A[i] # swap items
yield A[p:p+size] # return shuffled sub-range
输出:
A = list(range(100))
iG = iter(rndGroups(A,10)) # 10 groups of 10 items
s = set() # set to validate uniqueness
for _ in range(10): # 10 groups
g = next(iG) # get the next group from generator
s.update(g) # to check that all items are distinct
print(g)
print(len(s)) # must get 100 distinct values from groups
[87, 19, 85, 90, 35, 55, 86, 58, 96, 68]
[38, 92, 93, 78, 39, 62, 43, 20, 66, 44]
[34, 75, 72, 50, 42, 52, 60, 81, 80, 41]
[13, 14, 83, 28, 53, 5, 94, 67, 79, 95]
[9, 33, 0, 76, 4, 23, 2, 3, 32, 65]
[61, 24, 31, 77, 36, 40, 47, 49, 7, 97]
[63, 15, 29, 25, 11, 82, 71, 89, 91, 30]
[12, 22, 99, 37, 73, 69, 45, 1, 88, 51]
[74, 70, 98, 26, 59, 6, 64, 46, 27, 21]
[48, 17, 18, 8, 54, 10, 57, 84, 16, 56]
100
这将花费与预混洗列表一样长的时间(如果不是更长的话(,但它将允许您在进行时启动/馈送线程,从而增强并行性