繁体   English   中英

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

[英]How to generate a random partition from an iterator in Python

给定所需的分区数量,分区的大小应几乎相等。 这个问题解决了一个列表问题。 它们不具有random属性,但是很容易添加 我的问题是,我有一个迭代器作为输入,因此不适用shuffle 这样做的原因是我想随机划分图的节点。 该图可能非常大,因此我正在寻找一种解决方案,而不仅仅是创建一个中间列表。

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

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

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

您可以只创建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

通过根据每个分区中到目前为止生成的节点数来调整权重,可以使列表的长度更均匀。 如果选择一个函数,当(分区n中的节点数)>(节点数)/(分区数)时权重为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。 这种设计从本质上讲是较慢的,因为它需要遍历每个分区的节点列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM