我遇到如下问题:
我有两个数据帧
Dataframe DF1:
ID, Name, age
1 name1 18
2 name2 20
DataFrame DF2:
ID, Name, age
1 name1 18
3 name3 19
我正在尝试过滤DF2以按ID和名称排除DF1中包含的记录,以便我可以获得新的DF2
ID, Name, age
3 name3 19
然后联合这两个数据帧以获得最终结果:
ID, Name, age
1 name1 18
2 name2 20
3 name3 19
要在T-SQL中执行此操作,我可以编写类似
的语句INSERT INTO DF1
SELECT ID, Name, age FROM DF2 WHERE NOT EXISTS
(SELECT 1 FROM DF1 WHERE DF1.ID = DF2.ID AND DF1.Name = DF2.Name)
但我发现sparkSQL中的数据框架不支持“insert”。 所以我的问题是:
如何基于多列过滤数据框?
如何将两个数据帧组合在一起? 我很感激任何解决方案。
答案 0 :(得分:2)
假设记录是唯一的,实现目标的最简单方法是UNION
并按DISTINCT
跟进:
val df1 = Seq((1, "name1", 18), (2, "name2", 20)).toDF("ID", "Name", "age")
val df2 = Seq((1, "name1", 18), (3, "name3", 19)).toDF("ID", "Name", "age")
df1.unionAll(df2).distinct.show
// +---+-----+---+
// | ID| Name|age|
// +---+-----+---+
// | 1|name1| 18|
// | 2|name2| 20|
// | 3|name3| 19|
// +---+-----+---+
<强>特性强>:
df1
df1
和df2
进行随机播放
另一种方法是使用EXCEPT
后跟UNION
:
df1.unionAll(df2.except(df1)).show // df2.distinct.except to drop duplicates
// +---+-----+---+
// | ID| Name|age|
// +---+-----+---+
// | 1|name1| 18|
// | 2|name2| 20|
// | 3|name3| 19|
// +---+-----+---+
<强>属性强>:
df1
df3.unionAll(df2.except(df1))
)最后,如果您只希望部分匹配LEFT OUTER JOIN
,后跟UNION
过滤器应该可以解决问题:
df2.as("df2")
.join(
df1.select("id", "name").as("df1"),
// join on id and name
$"df1.id" === $"df2.id" && $"df1.name" === $"df2.name",
"leftouter")
// This could be replaced by .na.drop(...)
.where($"df1.id".isNull && $"df1.Name".isNull)
.select($"df2.id", $"df2.name", $"df2.age")
.unionAll(df1)
.show
// ---+-----+---+
// | ID| Name|Age|
// +---+-----+---+
// | 3|name3| 19|
// | 1|name1| 18|
// | 2|name2| 20|
// +---+-----+---+
<强>属性强>:
df1