2016-03-24 26 views
13

Nel SparkSQL 1.6 API (scala) Dataframe ha funzioni per intersecare e tranne, ma non uno per differenza. Ovviamente, una combinazione di unione e di eccezione può essere utilizzato per generare la differenza:Come ottenere la differenza tra due DataFrames?

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

Ma questo sembra un po 'scomodo. Nella mia esperienza, se qualcosa sembra imbarazzante, c'è un modo migliore per farlo, specialmente in Scala.

risposta

16

Si può sempre riscrivere come:

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

Seriamente, però questo UNION, INTERSECT e EXCEPT/MINUS è praticamente un set standard di operatori che conciliano SQL. Non sono a conoscenza di alcun sistema che fornisca operazioni simili a XOR fuori dalla scatola. Molto probabilmente perché è banale implementare usando altri tre e non c'è molto da ottimizzare lì.

+0

Grazie. Se fosse lì, probabilmente farebbe comunque qualcosa di simile sotto le coperte. – WillD

2

perché non il sottostante?

df1.except(df2) 
+0

Perché non esegue uno XOR. Cercavo tutti gli elementi NON all'incrocio. Il tuo codice restituisce solo gli elementi in d1 che non si trovano nell'intersezione. Ho anche bisogno di quelli in d2 che non sono nell'intersezione. – WillD

1

Si noti che i risultati del doppione EXCEPT (o MINUS che è solo un alias per EXCEPT). Quindi, se vi aspettate "tranne" set (diff lei ha citato) + "intersecano" impostato per essere uguale a dataframe originale, prendere in considerazione questa richiesta di funzione che mantiene i duplicati:

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

Come ho scritto lì ", SALVO ALL "può essere riscritto in Spark SQL come

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 
Problemi correlati