如何从Python中的迭代器生成随机分区

时间:2010-09-21 13:28:57

标签: python random iterator partitioning

给定所需的分区数量,分区的大小应该几乎相等。 This question处理列表的问题。它们没有随机属性,但那是easily added。我的问题是,我有一个迭代器作为输入,所以shuffle不适用。原因是我想随机分割图的节点。图表可能非常大,所以我正在寻找一种不只是创建中间列表的解决方案。

我的第一个想法是使用带有随机数函数的compress()作为选择器。但这只适用于两个分区。

3 个答案:

答案 0 :(得分:1)

你只是处理各种分区,对吗?

def dealer( iterator, size ):
    for item in iterator
        yield random.randrange( size ), item

这不是通过将每个项目分配给分区来开始的吗?

然后你可以做这样的事情来制作清单。也许不是一件好事,但它展示了如何使用该功能。

def make_lists( iterator, size ):
    the_lists = []*size
    for partition, item in dealer( iterator, size ):
        the_lists[partition].append(item)
    return the_lists

答案 1 :(得分:1)

你可以创建k列表。当您收到一个值时,选择一个介于0和k-1之间的随机整数x,并将该值放入第x个列表。

平均每个列表将包含N / k个元素,但标准差为√(N * 1 / k *(1-1 / k))。

def random_partition(k, iterable):
  results = [[] for i in range(k)]
  for value in iterable:
    x = random.randrange(k)
    results[x].append(value)
  return results

答案 2 :(得分:0)

通过根据每个分区中到目前为止生成的节点数调整权重,可以使列表的长度更加均匀。如果你选择一个函数使得当(分区n中的节点数)> 0时权重为0,它们将大致相等。 (节点数)/(分区数),即

weight [i] = max(numNodes / numPartitions - nodesSoFar [i],0)

(max()用于停止负权重,如果您有4个节点和3个分区,则可能会发生负权重。)

然后从1中选择一个随机数到总和(权重)(或0到总和(权重)-1)并适当选择分区。

如果您为每个分区使用不同的选择器,

compress()可以正常工作;像(x == n for x in random_partition_numbers)这样的东西,其中random_partition_numbers是一个生成器。当然,您需要为每个分区复制random_partition_numbers。这种设计本质上较慢,因为它需要遍历每个分区的节点列表。