In der SparkSQL
1.6-API (scala) hat Dataframe
Funktionen zum Überschneiden und Ausnahmen, jedoch keine für den Unterschied. Offensichtlich kann eine Kombination aus Vereinigung und Ausnahmen verwendet werden, um Unterschiede zu erzeugen:
df1.except(df2).union(df2.except(df1))
Dies erscheint jedoch etwas umständlich. Wenn etwas unangenehm erscheint, gibt es meiner Meinung nach einen besseren Weg, vor allem in Scala.
Sie können es immer wie folgt umschreiben:
df1.unionAll(df2).except(df1.intersect(df2))
Im Ernst, obwohl diese UNION
, INTERSECT
und EXCEPT
/MINUS
so ziemlich ein Standardsatz von SQL-Kombinationsoperatoren ist. Mir ist kein System bekannt, das XOR wie eine sofortige Bedienung ermöglicht. Am wahrscheinlichsten, weil es einfach ist, andere drei zu implementieren, und es gibt nicht viel zu optimieren.
warum nicht das unten?
df1.except(df2)
Beachten Sie, dass das EXCEPT (oder MINUS, das nur ein Alias für EXCEPT ist) de-dups führt. Wenn Sie also erwarten, dass "außer" set (der von Ihnen erwähnte Unterschied) + "intersect" gleich dem ursprünglichen Datenrahmen ist, sollten Sie diese Funktionsanforderung berücksichtigen, die Duplikate enthält:
https://issues.Apache.org/jira/browse/SPARK-21274
Wie ich dort schrieb, kann "EXCEPT ALL" in Spark SQL als neu geschrieben werden
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
Wenn Sie nach einer Pyspark-Lösung suchen, sollten Sie subtract () docs verwenden.
Außerdem ist unionAll in 2.0 veraltet. Verwenden Sie stattdessen union ().
df1.union(df2).subtract(df1.intersect(df2))