繁体   English   中英

如何在python中比较具有相同PCollection的两个键的所有值?

[英]How to compare all the values of two keys with in same PCollection in python?

我是 Apache Beam/数据流的新手。 我正在 Apache Beam 中读取 BigQuery 表,我想按两个不同的列进行分组并比较两个不同键的所有值。 我创建了一个由两个不同列(ID、Date)组成的元组,用作 Key。 以下是表格中的示例数据

  ID         Date        P_id    position
  "abc"    2019-08-01   "rt56"      5
  "abc"    2019-08-01   "rt57"      6
  "abc"    2019-08-01   "rt58"      7
  "abc"    2019-08-02   "rt56"      2 
  "abc"    2019-08-02   "rt57"      4
  "abc"    2019-08-02   "rt58"      7

现在我想比较 P_ids 对 ("abc", 2019-08-01) 和 ("abc", 2019-08-02) 的位置,看看是否有任何 P_id 位置发生变化,然后在表“状态”为 True。 所以我的新表应该如下所示

我正在尝试使用以下代码

  ID         Date        P_id    position  Status
  "abc"    2019-08-01   "rt56"      5       False (as this is first date)
  "abc"    2019-08-01   "rt57"      6
  "abc"    2019-08-01   "rt58"      7
  "abc"    2019-08-02   "rt56"      2       True
  "abc"    2019-08-02   "rt57"      4
  "abc"    2019-08-02   "rt58"      7
(
p 
| "get_key_tuple" >> beam.ParDo(lambda element: tuple(element["Id"], element["Date]))
| "group_by" >> beam.GroupByKey()
| "compare_and_add_status" >> beam.ParDo(compare_pos)
)

但我不知道我应该如何处理函数 compare_pos()

考虑到我有一个非常大的表格和很多 ID,获得一些关于如何有效地比较位置并创建一个新列以了解状态的想法将非常有帮助。

Beam 的 GroupByKey 采用 2 元组的 PCollection 并返回一个 PCollection,其中每个元素都是键的 2 元组和与该键关联的所有值的(无序)可迭代对象。 例如,如果您的原始集合具有元素

(k1, v1)
(k1, v2)
(k1, v3)
(k2, v4)

GroupByKey 的结果将是一个带有类似元素的 PCollection

(k1, [v1, v3, v2])
(k2, [v4])

在您的情况下,您的键和值本身就是元组。 因此,您可以使用原始集合并应用Map(lambda elt: ((elt['Id'], elt['Date']), (elt['P_id'], elt['position'])))会给你一个带有元素的 PCollection

  ("abc", 2019-08-01),   ("rt56", 5)
  ("abc", 2019-08-01),   ("rt57", 6)
  ("abc", 2019-08-01),   ("rt58", 7)
  ("abc", 2019-08-02),   ("rt56", 2)
  ("abc", 2019-08-02),   ("rt57", 4)
  ("abc", 2019-08-02),   ("rt58", 7)

其中,在应用 GroupByKey 后将成为

  ("abc", 2019-08-01),   [("rt56", 5), ("rt57", 6), ("rt58", 7)]
  ("abc", 2019-08-02),   [("rt56", 2), ("rt57", 4), ("rt58", 7)]

此时,您的compare_pos函数可以检查与给定ID, Date对相对应的所有P_id, position元组ID, Date并执行发出需要更改的内容(及其相应的键)所需的任何逻辑。

我可能对 OP 的解释有误,但如果 @robertwb 的建议不起作用,请尝试按以下方式分组:

| "Create k, v tuple" >> beam.Map(
                    lambda elem: ((elem["P_id"], elem["ID"]), [elem["Date"], elem["position"]]))
| "Group by key" >> beam.GroupByKey()

这将输出以下结构:

(('rt56', 'abc'), [['2019-08-01', 5], ['2019-08-02', 2]])
(('rt57', 'abc'), [['2019-08-01', 6], ['2019-08-02', 4]])
(('rt58', 'abc'), [['2019-08-01', 7], ['2019-08-02', 7]])

这应该允许您单独比较生成的 PCollection 中的每个元素,而不是在 PCollection 中的元素之间进行交叉比较。 如果我是对的,这应该更适合 Beam 的执行模型。

这是基于我的假设,即您想要检查给定 P_id 的位置是否在两个日期之间发生了变化。

暂无
暂无

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

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