【发布时间】:2018-06-03 17:20:52
【问题描述】:
假设我有两个 DataFrame -- df1 和 df2 -- 都有 foo 和 bar 列。 foo 列是一个 CRC32 哈希值,如 123456,bar 列是一个布尔字段,默认为 False。
在 pyspark 中,比较两个 DataFrame 中 foo 的值的有效方法是什么,如果它们不匹配,则将列 bar 写入 True。
例如,给定以下两个 DataFrame:
# df1
foo | bar
-------|------
123456 | False
444555 | False
666777 | False
888999 | False
# df2
foo | bar
-------|------
938894 | False
129803 | False
666777 | False
888999 | False
我想要一个如下所示的新 DataFrame,其中两个 True 列的哈希值发生了变化:
# df3
foo | bar
-------|------
938894 | True <---
129803 | True <---
666777 | False
888999 | False
任何指导将不胜感激。
2018 年 7 月 1 日更新
在成功使用接受的答案很长一段时间后,遇到了一种情况,使解决方案不太适合。如果连接中的一个 DataFrame 中的多行与连接中另一个 DataFrame 中的行具有相同的 foo 值,则会导致该共享值上的行的笛卡尔积增长。
在我的例子中,我有基于空字符串的 CRC32 哈希值,这导致哈希值 0。我还应该补充一点,我确实有一个唯一的字符串来匹配上面的行,在 id 下(可能有过于简单的情况),也许 这是要加入的事情:
它会产生这样的情况:
# df1
id |foo | bar
-----|-------|------
abc |123456 | False
def |444555 | False
ghi |0 | False
jkl |0 | False
# df2
id |foo | bar
-----|-------|------
abc |123456 | False
def |999999 | False
ghi |666777 | False
jkl |0 | False
如果选择了答案,将会得到一个数据框,其中包含 更多 行:
# df3
id |foo | bar
-----|-------|------
abc |123456 | False
def |999999 | True <---
ghi |0 | False
jkl |0 | False
jkl |0 | False # extra row add through join
我将保留选择的答案,因为它是对最初提出的问题的一个很好的答案。但是,对于如何处理 foo 列可能匹配的 DataFrame 的任何建议,我们将不胜感激。
2018 年 7 月 1 日的另一个更新,替代答案
如果没有加入 id 列,我已经把问题复杂化了。使用它时,根据fingerprint 列的直接比较,加入和编写transformed 列相对简单:
df2.alias("df2").join(df1.alias("df1"), df1.id == df2.id, 'left')\
.select(f.col('df2.foo'), f.when(df1.fingerprint != df2.fingerprint, f.lit(True)).otherwise(f.col('df2.bar')).alias('bar'))\
.show(truncate=False)
【问题讨论】:
标签: apache-spark dataframe pyspark