我们说我有两个数据框架 - df1
和df2
- 两者都有foo
和bar
列。列foo
是CRC32哈希值,如123456
,列bar
是布尔字段,默认为False
。
在pyspark中,比较foo
在两个数据框架中的值的有效方法是,如果不是<<},则将列bar
写入True
/ strong>匹配。
# 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
非常感谢任何指导。
成功使用已接受的答案已经有一段时间了,遇到一种情况会使解决方案不太合适。如果其中一个联接的DataFrame中的多个行与foo
的值相同,而是来自联接中其他DataFrame的行,则会导致该共享值上的行的笛卡尔积增长。
在我的情况下,我有基于空字符串的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的任何建议,将不胜感激。
如果没有id
列加入,我就会使问题复杂化。使用它时,根据transformed
列的直接比较,加入和编写fingerprint
列相对简单:
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)
答案 0 :(得分:2)
使用df2
df1
的{em>别名左连接并使用when
函数检查不匹配的逻辑应该给你你想要的输出
df2.alias("df2").join(df1.alias("df1"), df1.foo == df2.foo, 'left')\
.select(f.col('df2.foo'), f.when(f.isnull(f.col('df1.foo')), f.lit(True)).otherwise(f.col('df2.bar')).alias('bar'))\
.show(truncate=False)
应该给你
+------+-----+
|foo |bar |
+------+-----+
|129803|true |
|938894|true |
|888999|false|
|666777|false|
+------+-----+
答案 1 :(得分:0)
我建议使用左连接并编写代码,以便当数据为null时输出false,反之亦然。