在Spark 1.6 API(Scala)中,Dataframe有用于intersect和except的函数,但没有用于difference的函数。显然,union和except的组合可以用来生成差异:
Spark
Dataframe
df1.except(df2).union(df2.except(df1))
但这似乎有点尴尬。根据我的经验,如果有些事情看起来很尴尬,有一个更好的方法来做,特别是在Scala中。
tcbh2hod1#
你总是可以把它重写为:
df1.unionAll(df2).except(df1.intersect(df2))
说真的,UNION、INTERSECT和EXCEPT/MINUS几乎是一组标准的SQL组合运算符。我不知道任何系统提供异或一样的操作开箱即用。最有可能的原因是,使用其他三个实现它是微不足道的,并且没有太多的优化。
UNION
INTERSECT
EXCEPT
MINUS
iyr7buue2#
为什么不是下面呢?
df1.except(df2)
8e2ybdfx3#
如果你正在寻找Pyspark解决方案,你应该使用subtract()docs。此外,unionAll在2.0中不推荐使用,请使用union()。df1.union(df2).subtract(df1.intersect(df2))
df1.union(df2).subtract(df1.intersect(df2))
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
dxxyhpgq5#
我认为使用左连接然后过滤空值会更有效。
df1.join(df2, Seq("some_join_key", "some_other_join_key"),"left") .where(col("column_just_present_in_df2").isNull)
5条答案
按热度按时间tcbh2hod1#
你总是可以把它重写为:
说真的,
UNION
、INTERSECT
和EXCEPT
/MINUS
几乎是一组标准的SQL组合运算符。我不知道任何系统提供异或一样的操作开箱即用。最有可能的原因是,使用其他三个实现它是微不足道的,并且没有太多的优化。iyr7buue2#
为什么不是下面呢?
8e2ybdfx3#
如果你正在寻找Pyspark解决方案,你应该使用subtract()docs。
此外,unionAll在2.0中不推荐使用,请使用union()。
df1.union(df2).subtract(df1.intersect(df2))
3duebb1j4#
请注意,EXCEPT(或MINUS,它只是EXCEPT的别名)会重复数据消除结果。因此,如果你期望“except”set(你提到的diff)+“intersect”set等于原始的数组,考虑这个保留重复的特性请求:
https://issues.apache.org/jira/browse/SPARK-21274
正如我在那里写的,“EXCEPT ALL”可以在Spark SQL中重写为
dxxyhpgq5#
我认为使用左连接然后过滤空值会更有效。