2016-03-24 20 views
13

Interfejs API 1.6 (scala) SparkSQL ma funkcje przecinające się i wykluczające różnicę. Oczywiście, kombinacja unii i oprócz może być użyta do wygenerowania różnicy:Jak uzyskać różnicę między dwoma elementami DataFrames?

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

Ale wydaje się to trochę niezręczne. Z mojego doświadczenia, jeśli coś wydaje się niezręczne, jest lepszy sposób na zrobienie tego, szczególnie w Scali.

Odpowiedz

16

Zawsze można przepisać jako:

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

Poważnie jednak tego UNION, INTERSECT i EXCEPT/MINUS jest dość dużo standardowy zestaw SQL łączących operatorów. Nie jestem świadomy żadnego systemu, który zapewnia obsługę XOR po wyjęciu z pudełka. Najprawdopodobniej dlatego, że wdrożenie trzech innych metod jest banalne i nie ma tu zbyt wiele do zoptymalizowania.

+0

Dzięki. Gdyby tam był, i tak prawdopodobnie zrobiłby coś takiego pod kołdrą. – WillD

2

dlaczego nie poniżej?

df1.except(df2) 
+0

Ponieważ to nie wykonuje XOR. Szukałem wszystkich elementów, NIE w przecięciu. Twój kod zwraca tylko elementy w d1, które nie znajdują się na przecięciu. Też potrzebuję tych w d2, które nie są na przecięciu. – WillD

1

Należy zauważyć, że EXCEPT (lub MINUS, który jest tylko aliasem dla opcji EXCEPT) usuwa wyniki. Więc jeśli można oczekiwać „z wyjątkiem” set (diff wspomniałeś) + „przecinają” ustawiony jest równa oryginalnej dataframe rozważyć ten wniosek cecha, która utrzymuje duplikaty:

https://issues.apache.org/jira/browse/SPARK-21274

Jak pisałem tam, „z wyjątkiem ALL "można przepisać w Spark SQL jako

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 
Powiązane problemy