web-dev-qa-db-de.com

Wie erhalte ich den Unterschied zwischen zwei DataFrames?

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. 

17
WillD

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.

24
zero323

warum nicht das unten?

df1.except(df2)
4
Tal Barda

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
1
Tagar

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))

0
Aaron