Scala 如何获得两个数据帧之间的对称差?
在Scala 如何获得两个数据帧之间的对称差?,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,在SparkSQL1.6api(scala)Dataframe中有用于intersect和except的函数,但没有用于difference的函数。显然,union和except的组合可用于产生差异: df1.except(df2).union(df2.except(df1)) 但这似乎有点尴尬。根据我的经验,如果某件事情看起来很尴尬,有更好的方法来做,尤其是在Scala中 您始终可以将其重写为: df1.unionAll(df2).except(df1.intersect(df2)) 严肃
SparkSQL
1.6api(scala)Dataframe
中有用于intersect和except的函数,但没有用于difference的函数。显然,union和except的组合可用于产生差异:
df1.except(df2).union(df2.except(df1))
但这似乎有点尴尬。根据我的经验,如果某件事情看起来很尴尬,有更好的方法来做,尤其是在Scala中 您始终可以将其重写为:
df1.unionAll(df2).except(df1.intersect(df2))
严肃地说,尽管这个并集
,相交
和除
/减
外,几乎是一组标准的SQL组合运算符。我不知道有哪一个系统提供了开箱即用的XOR操作。最有可能的原因是,使用其他三个实现起来很简单,而且没有太多可优化的地方。为什么不使用下面的方法呢
df1.except(df2)
请注意,EXCEPT(或减号,它只是EXCEPT的别名)重复数据消除结果。因此,如果您期望“除”SET(您提到的差异)+“交叉”设置为等于原始数据框,请考虑保留重复的特征请求:
正如我在那里写的,“除了所有”可以在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
我认为使用左连接然后过滤掉空值会更有效
df1.join(df2, Seq("some_join_key", "some_other_join_key"),"left")
.where(col("column_just_present_in_df2").isNull)
如果您正在寻找Pyspark解决方案,则应使用subtract() 此外,unionAll在2.0中不推荐使用,请改用union()
df1.union(df2).subtract(df1.intersect(df2))
谢谢。如果它在那里,它可能会在封面下做类似的事情,因为它不会执行XOR。我在寻找不在十字路口的所有元素。您的代码只返回d1中不在交叉点的元素。我还需要d2中不在交叉口的那些。1)不喜欢重复的。出于这个问题的考虑,这里的DFs可以被视为集合。2) 最初的问题是针对Spark,而不是SparkSQL。我更喜欢函数式的编码方式。我相信你要找的短语是“对称差异”。这和被否决的原因有关吗?pyspark没有except()
,但有subtract()
,它似乎具有与批准的解决方案中提供的功能类似的功能。未意识到给出了-1。是的,我也很想知道它被否决的原因