如何在Spark Dataframe中使用Except函数

时间:2018-12-04 06:51:10

标签: scala apache-spark

我想得到两个数据框之间的差异,但只返回具有不同字段的行。例如,我有2个数据框,如下所示:

val DF1 = Seq(
    (3,"Chennai",  "rahman",9846, 45000,"SanRamon"),
    (1,"Hyderabad","ram",9847, 50000,"SF")
).toDF("emp_id","emp_city","emp_name","emp_phone","emp_sal","emp_site")

val DF2 = Seq(
    (3,"Chennai",  "rahman",9846, 45000,"SanRamon"),
    (1,"Sydney","ram",9847, 48000,"SF")
).toDF("emp_id","emp_city","emp_name","emp_phone","emp_sal","emp_site")

这两个数据帧之间的唯一区别是第二行的emp_cityemp_sal。 现在,我正在使用except函数,该函数将整行显示如下:

DF1.except(DF2)

+------+---------+--------+---------+-------+--------+
|emp_id| emp_city|emp_name|emp_phone|emp_sal|emp_site|
+------+---------+--------+---------+-------+--------+
|     1|Hyderabad|     ram|     9847|  50000|      SF|
+------+---------+--------+---------+-------+--------+

但是,我需要这样的输出:

+---------+--------+-----+
|emp_id| emp_city|emp_sal|
+------+---------+-------+
|     1|Hyderabad|  50000| 
+------+---------+-------+

其中显示了不同的单元格以及emp_id

编辑: 如果列中有更改,则应显示,如果没有更改,则应将其隐藏或为空

3 个答案:

答案 0 :(得分:1)

您应该考虑@ user238607的评论,因为我们无法预测哪些列会有所不同,

仍然可以尝试此解决方法。

我假设l_e1 = tf_l1 == rm_l1 l_e2 = tf_l2 == rm_l2 l_eb = tf_bl == rm_bl l_t_e1 = tf_t_l1 == rm_t_l1 l_t_e2 = tf_t_l2 == rm_t_l2 l_t_eb = tf_t_bl == rm_t_bl l_e1, l_e2, l_eb, l_t_e1, l_t_e2, l_t_eb # (False, False, False, False, False, False) 是唯一的

emp_id

答案 1 :(得分:1)

以下应该给你你正在寻找的结果。

DF1.except(DF2).select("emp_id","emp_city","emp_sal")

答案 2 :(得分:0)

我发现此解决方案似乎运行良好:

val cols = DF1.columns.filter(_ != "emp_id").toList
val DF3 = DF1.except(DF2)
def mapDiffs(name: String) = when($"l.$name" === $"r.$name", null ).otherwise(array($"l.$name", $"r.$name")).as(name)
val result = DF2.as("l").join(DF3.as("r"), "emp_id").select($"emp_id" :: cols.map(mapDiffs): _*)

它生成如下输出:

+------+-------------------+--------+---------+--------------+--------+
|emp_id|           emp_city|emp_name|emp_phone|       emp_sal|emp_site|
+------+-------------------+--------+---------+--------------+--------+
|     1|[Sydney, Hyderabad]|    null|     null|[48000, 50000]|    null|
|    
+------+-------------------+--------+---------+--------------+--------+