Filtring PCollection基于python数据流中另一个PCollection的值

时间:2018-01-06 16:11:51

标签: google-cloud-dataflow apache-beam

我有两个P-Collection,如下所示

  

P1 = [' 1',' 2',' 4',' 5',' 6' &#39 7'&#39 8']

     

P2 = [(' 1',(2,1,2)),(' 5',(1,0,9)),(' 9& #39;,(1,2,3)),(' 10',(1,0,0)),   (' 1',(1,1,1))]

我想使用dataflow python编写Combiner,以便我的P2将被过滤,如下所示

  

结果= [(' 1',(2,1,2)),(' 5',(1,0,9)),(' 1& #39;,(1,1,1))]

这将是优化和快速的方法吗?

1 个答案:

答案 0 :(得分:1)

这是解决这个问题的一种可行方法:

def extract_keys(row):
    for e in row[1]['p2']:
        yield (row[0], e)

p = beam.Pipeline(options=beam.pipeline.StandardOptions())
p1 = p | 'p1' >> beam.Create([[str(i), 1] for i in range(8)])
p2 = p | 'p2' >> beam.Create([('1',(2,1,2)), ('5', (1,0,9)), ('9', (1,2,3)), ('10', (1,0,0)), ('1',(1,1,1))])
p3 = ({'p1': p1, 'p2': p2} 
       |'Group all keys' >> beam.CoGroupByKey()
       | 'Filter' >> beam.Filter(lambda x: (len(x[1]['p2']) > 0 and len(x[1]['p1']) > 0))
       | 'Extract keys' >> beam.FlatMap(lambda x: extract_keys(x))
       | 'Save results' >>  beam.io.WriteToText('result.csv'))

结果如何:

('1', (2, 1, 2))
('1', (1, 1, 1))
('5', (1, 0, 9))

这里发生了什么:首先注意我必须使用与你的输入略有不同的输入。我的P1就像[['1', 1], ['2', 1]...]。这样我们就可以在CoGroupByKey操作中使用它,将PCollections混合成一个使用键作为合并的参考(注意PCollections在此步骤中位于dict内,因为这是预期的由CoGroupByKey)输入。

在完成之后,我们只过滤掉没有任何匹配的密钥。 extract_keys仅用于获取您要查找的预期输出。

我建议您使用这些步骤,例如,您可以删除p3中的一些步骤,并查看每个操作的结果,以查看数据的转换方式。此外,these snippets可能会为您提供有关这些转换如何运作的一些想法。