我有两个Spark数据帧,df1
和df2
:
+-------+-----+---+
| name|empNo|age|
+-------+-----+---+
|shankar|12121| 28|
| ramesh| 1212| 29|
| suresh| 1111| 30|
| aarush| 0707| 15|
+-------+-----+---+
+------+-----+---+-----+
| eName| eNo|age| city|
+------+-----+---+-----+
|aarush|12121| 15|malmo|
|ramesh| 1212| 29|malmo|
+------+-----+---+-----+
我需要根据另一个文件中指定的列数,从df1
获取非匹配记录。
例如,列查找文件如下所示:
df1col,df2col
name,eName
empNo, eNo
预期输出为:
+-------+-----+---+
| name|empNo|age|
+-------+-----+---+
|shankar|12121| 28|
| suresh| 1111| 30|
| aarush| 0707| 15|
+-------+-----+---+
这个想法是如何为上述场景动态构建where条件,因为查找文件是可配置的,因此它可能有1到n个字段。
答案 0 :(得分:3)
您可以使用except
数据框方法。为了简单起见,我假设要使用的列在两个列表中。必须使两个列表的顺序正确,将比较列表中相同位置的列(无论列名称如何)。在except
之后,使用join
从第一个数据框中获取缺少的列。
val df1 = Seq(("shankar","12121",28),("ramesh","1212",29),("suresh","1111",30),("aarush","0707",15))
.toDF("name", "empNo", "age")
val df2 = Seq(("aarush", "12121", 15, "malmo"),("ramesh", "1212", 29, "malmo"))
.toDF("eName", "eNo", "age", "city")
val df1Cols = List("name", "empNo")
val df2Cols = List("eName", "eNo")
val tempDf = df1.select(df1Cols.head, df1Cols.tail: _*)
.except(df2.select(df2Cols.head, df2Cols.tail: _*))
val df = df1.join(broadcast(tempDf), df1Cols)
结果数据框看起来像是想要的:
+-------+-----+---+
| name|empNo|age|
+-------+-----+---+
| aarush| 0707| 15|
| suresh| 1111| 30|
|shankar|12121| 28|
+-------+-----+---+
答案 1 :(得分:0)
如果您是从SQL查询执行此操作,我将使用Changing a SQL column title via query之类的内容重新映射SQL查询本身中的列名。您可以在查询中执行简单的文本替换,以将它们规范化为df1或df2列名称。
一旦你有了这个,你就可以使用像 How to obtain the difference between two DataFrames?
如果您需要更多不在diff中使用的列(例如age),您可以根据diff结果重新选择数据。这可能不是最佳方式,但可能会有效。