scala 如何获得两个DataFrame之间的对称差?

0tdrvxhp  于 2023-10-18  发布在  Scala
关注(0)|答案(5)|浏览(157)

Spark 1.6 API(Scala)中,Dataframe有用于intersect和except的函数,但没有用于difference的函数。显然,union和except的组合可以用来生成差异:

df1.except(df2).union(df2.except(df1))

但这似乎有点尴尬。根据我的经验,如果有些事情看起来很尴尬,有一个更好的方法来做,特别是在Scala中。

tcbh2hod

tcbh2hod1#

你总是可以把它重写为:

df1.unionAll(df2).except(df1.intersect(df2))

说真的,UNIONINTERSECTEXCEPT/MINUS几乎是一组标准的SQL组合运算符。我不知道任何系统提供异或一样的操作开箱即用。最有可能的原因是,使用其他三个实现它是微不足道的,并且没有太多的优化。

iyr7buue

iyr7buue2#

为什么不是下面呢?

df1.except(df2)
8e2ybdfx

8e2ybdfx3#

如果你正在寻找Pyspark解决方案,你应该使用subtract()docs。
此外,unionAll在2.0中不推荐使用,请使用union()。
df1.union(df2).subtract(df1.intersect(df2))

3duebb1j

3duebb1j4#

请注意,EXCEPT(或MINUS,它只是EXCEPT的别名)会重复数据消除结果。因此,如果你期望“except”set(你提到的diff)+“intersect”set等于原始的数组,考虑这个保留重复的特性请求:
https://issues.apache.org/jira/browse/SPARK-21274
正如我在那里写的,“EXCEPT ALL”可以在Spark SQL中重写为

SELECT a,b,c
FROM    tab1 t1
     LEFT OUTER JOIN 
        tab2 t2
     ON (
        (t1.a, t1.b, t1.c) = (t2.a, t2.b, t2.c)
     )
WHERE
    COALESCE(t2.a, t2.b, t2.c) IS NULL
dxxyhpgq

dxxyhpgq5#

我认为使用左连接然后过滤空值会更有效。

df1.join(df2, Seq("some_join_key", "some_other_join_key"),"left")
.where(col("column_just_present_in_df2").isNull)

相关问题