Python 是否将pcollection的每一行拆分为多个pcollection?

Python 是否将pcollection的每一行拆分为多个pcollection?,python,apache-beam,Python,Apache Beam,在我做了一些处理并按键分组之后,我有了一个如下所示的数据集。我现在需要对每一行数据进行一些处理,以获得下面的输出。我试过flatmap,它非常慢,因为“值”列表的长度可以任意长。我想我可以将每一行分割成单独的PCollection,并行处理,然后将它们放在一起。如何将每行拆分为不同的pcollection?如果这不可行,有没有其他方法可以加快计算速度 输入 输出: key, value 1 (A, 0) 1 (B, 1) 1 (B, 2) 1 (B, 3) 2 (A

在我做了一些处理并按键分组之后,我有了一个如下所示的数据集。我现在需要对每一行数据进行一些处理,以获得下面的输出。我试过flatmap,它非常慢,因为“值”列表的长度可以任意长。我想我可以将每一行分割成单独的PCollection,并行处理,然后将它们放在一起。如何将每行拆分为不同的pcollection?如果这不可行,有没有其他方法可以加快计算速度

输入

输出:

key, value
1    (A, 0)
1    (B, 1)
1    (B, 2)
1    (B, 3)
2    (A, 0)
2    (B, 1)
2    (B, 2)
2    (B, 3)
...

在使用apachebeam模型时,一个常见的误解是并行化方案是由PCollection定义的(可以理解,因为这是Parallel Collection的缩写)。实际上,并行化是在每个PCollection[1]中为每个键定义的。换句话说,梁模型并行处理键,但按顺序处理单个键中的值

您遇到的问题通常被称为热键。当太多的值与单个键配对时会发生这种情况,从而限制了并行性

要将数据操纵到预期的输出,您必须编辑现有管道,以使并非所有元素都指向单个键的方式发出值。这有点困难,因为在您的示例中,您希望输出包含元素的索引。如果是这种情况,那么无论您如何剪切它,您都必须将所有的值合并到内存中的某个键,以获得正确的索引

如果您不想像上面的例子那样获取特定的索引,那么请看下面的代码。此代码将每个元素分配给每个键内的随机分区。这有助于将每个键的元素数分解为可管理的元素

data = [
  (k, c) for k in range(1, 6) for c in ('A', 'B', 'B', 'B')
]

p = beam.Pipeline()
elems = p | beam.Create(data)

num_buckets = 4

class Preprocess(beam.DoFn):
  def process(self, el):
    key = str(el[0])
    partition = random.randint(0, num_buckets)
    yield (key, partition), el

class Postprocess(beam.DoFn):
  def process(self, el):
    (key, partition), values = el
    index = 0
    for el in values:
      yield key, (el[1], partition, index)
      index += 1
    
out = (elems | beam.ParDo(Preprocess())
             | beam.GroupByKey()
             | beam.ParDo(Postprocess()))

输入

潜在产出

key,(value,partition,index)
1   ('A', 1, 0)
1   ('B', 1, 1)
1   ('B', 2, 0)
1   ('B', 3, 0)
2   ('A', 3, 0)
2   ('B', 3, 1)
2   ('B', 1, 0)
2   ('B', 1, 1)
3   ('A', 3, 0)
3   ('B', 2, 0)
...

[1] 使用流式传输时,它是按每个窗口的每个键定义的

为什么不只是迭代GBK结果中的值?许多PCollection对我来说没有意义(只有当它们包含不同类型的元素并且必须遵循下游处理的不同路径时),因为PCollection按设计应该是并行处理的。我确实尝试过。我编写了一个函数,并使用flatmap将该函数应用于pcollection,它非常慢,有时会耗尽内存。“值”列表的长度可以任意长(数十万)。我希望将其拆分为多个PCollection将有助于加快速度。这并不是我想要的,但它给了我一个帮助解决问题的想法。谢谢NP如果可能的话,如果你能为你如何解决这个问题添加一个答案,那就太好了。我很想知道你想出了什么解决方案。Heyl我对Beam有点陌生,并试图理解它;你能给我指一指显示Beam内部工作的资源吗?它能帮助我得出你所说的这句话的结论,“Beam模型并行处理键,但顺序处理单个键中的值。”
key,value
1   A
1   B
1   B
1   B
2   A
2   B
2   B
2   B
3   A
3   B
...
key,(value,partition,index)
1   ('A', 1, 0)
1   ('B', 1, 1)
1   ('B', 2, 0)
1   ('B', 3, 0)
2   ('A', 3, 0)
2   ('B', 3, 1)
2   ('B', 1, 0)
2   ('B', 1, 1)
3   ('A', 3, 0)
3   ('B', 2, 0)
...