Scala Spark,比较两个 DataFrame 并选择另一列的值

Posted

技术标签:

【中文标题】Scala Spark,比较两个 DataFrame 并选择另一列的值【英文标题】:Scala Spark, compare two DataFrames and select the value of another column 【发布时间】:2021-02-25 15:01:17 【问题描述】:

我有两个数据框。我真正想做的是:

如果列 Name 是“P”,那么我必须选择名为 FinalValue 的列DF2 列 id_1 与 DF2 的列 Id_name 匹配,否则我必须用空值填充它。

例如,我有以下 DataFrames(DF1 和 DF2):

+--------+-------+-------+
|Name    | value | id_1  |
+- ------+-------+-------+
|P       |5      | being |      
|X       |1      | dose  |
|Z       |1      | yex   |

df2
+--------+------------+
|Id_name | FinalValue |
+- ------+------------+
|ash     | h32        |
|being   | c11        |
|dose    | g21        |

在这种情况下,输出应该是:

+--------+-------+-------------+
|Name    | value | FinalValue  | 
+- ------+-------+-------------+
|P       |5      | c11         |      
|X       |1      | null        |
|Z       |1      | null        |

我正在尝试的是以下内容:

var df3 = df1.withColumn("FinalValue", when($"Name" === "P", df2.select(...)))

但是如您所见,我不知道如何继续,因为如果我选择 DF2 的一列,我就无法选择另一列 DF1。我该怎么做?

也许我的解释不够好,如果您需要更多信息或解释,请告诉我。提前致谢。

【问题讨论】:

【参考方案1】:

您可以进行左连接,然后使用when 屏蔽最终值:

val df3 = df1.join(
    df2,
    df1("id_1") === df2("Id_name"),
    "left"
).select(
    df1.columns.dropRight(1).map(col) :+
    when($"Name" === "P", $"FinalValue").as("FinalValue")
    : _*
)

df3.show
+----+-----+----------+
|Name|value|FinalValue|
+----+-----+----------+
|   P|    5|       c11|
|   X|    1|      null|
|   Z|    1|      null|
+----+-----+----------+

【讨论】:

这可以工作,但是如果两个数据框中的连接列的名称不同?我该怎么做? 例如 Name 和 N_id ? @MLstudent 你的意思是 df1 中除 id_1 之外的所有列吗?您可以查看我编辑的答案 dropRight 从列名列表中删除最后一个元素。 map 将每个列表元素转换为列对象 :+ 将一列附加到列列表中,并且 :_* 将列表扩展为可变参数。

以上是关于Scala Spark,比较两个 DataFrame 并选择另一列的值的主要内容,如果未能解决你的问题,请参考以下文章

Spark 中的数据框比较:Scala

Scala Spark,比较两个 DataFrame 并选择另一列的值

关于Spark、Scala实现WordCount的8种写法(多种写法)

Scala - 基于 Spark 中的键合并两个 RDD

spark scala比较具有时间戳列的数据帧

在 Apache Spark (Scala) 上获取两个数据帧的差异