如果第一个数据帧中存在行,如何更新第二个数据帧的存在值

Posted

技术标签:

【中文标题】如果第一个数据帧中存在行,如何更新第二个数据帧的存在值【英文标题】:how to update second dataframe's exists value if row exists in first dataframe 【发布时间】:2020-11-23 20:49:51 【问题描述】:

我有两个数据框,我想检查 df1 是否包含 df2 中键为 a 和 b 的任何行,如果相等,则在 df2 中更改为 true,并添加 df1 中的新行,其中存在 False

df1

a | b | c | d
1 | 1 | 3 | 4
2 | 2 | 4 | 1
3 | 3 | 5 | 3

df2

a | b | c | d
1 | 1 | 4 | 5
4 | 4 | 3 | 2

这应该看起来像

df3

a | b | c | d | exists
1 | 1 | 4 | 5 | True
4 | 4 | 3 | 2 | False
1 | 1 | 3 | 4 | False
2 | 2 | 4 | 1 | False
3 | 3 | 5 | 3 | False

到目前为止我有这个

val newdf = df1.join(df2, df1("a")===df2("a") && df1("b") === df2("b"), "left")
   .select(df2("a"), df2("b"),df2("c"),df2("d"),when(df2("a").isNull, false).otherwise(true).alias("exists"))

返回

a | b | c | d | exists
1 | 1 | 4 | 5 | True
rest of the rows are null 

【问题讨论】:

1 | 1 | 3 | 4 | False 这一行是否也会出现在 df3 中?因为 df1 中有匹配的行.. 是的,两个数据框中的所有行都将在 df3 中。与 df2 匹配的那个将在 df3 中存在 【参考方案1】:

尝试加入 left_semi, left_anti,然后加入 unionAll 数据集。

Example:

df2.join(df1,Seq("a","b"),"left_semi").withColumn("exists",lit("True")).
unionAll(df2.join(df1,Seq("a","b"),"left_anti").withColumn("exists",lit("False"))).
unionAll(df1.withColumn("exists",lit("False"))).show()
//+---+---+---+---+------+
//|  a|  b|  c|  d|exists|
//+---+---+---+---+------+
//|  1|  1|  4|  5|  True|
//|  4|  4|  3|  2| False|
//|  1|  1|  3|  4| False|
//|  2|  2|  4|  1| False|
//|  3|  3|  5|  3| False|
//+---+---+---+---+------+

【讨论】:

这行得通,谢谢另外一件事,df2 用作真值表,因此下次读取它时,它将具有存在列。如果我补充说我得到这个错误 Union can only be executed on tables with the same number of columns, but first table has 8 columns and the 2th table has 7 columns;;

以上是关于如果第一个数据帧中存在行,如何更新第二个数据帧的存在值的主要内容,如果未能解决你的问题,请参考以下文章

如何根据来自其他 pyspark 数据帧的日期值过滤第二个 pyspark 数据帧?

使用 merge() 使用第二个数据帧中的值更新数据帧

如果 pyspark 数据帧的行基于两列的值位于另一个数据帧中,如何删除它们?

如果日期介于第二个数据帧中的两个日期之间,则 r 标记第一个数据帧中的行

根据第二个数据帧的匹配列更新熊猫数据帧

如何根据第二个数据帧映射第一个数据帧中的值?