2016-03-24 2 views
13

В SparkSQL 1.6 API (scala) Dataframe имеет функции для пересечения и за исключением, но не для разницы. Очевидно, что сочетание союза и, за исключением может быть использован для создания разницы:Как получить разницу между двумя DataFrames?

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

Но это, кажется, немного неудобно. По моему опыту, если что-то кажется неудобным, есть лучший способ сделать это, особенно в Scala.

ответ

16

Вы всегда можете переписать как:

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

серьезно, хотя этого UNION, INTERSECT и EXCEPT/MINUS довольно много стандартный набор SQL сочетающих операторов. Я не знаю какой-либо системы, которая предоставляет XOR как операцию из коробки. Скорее всего, потому что тривиально реализовать с помощью других трех, и там не так много оптимизировать.

+0

Спасибо. Если бы он был там, это, вероятно, все-таки сделало бы что-то вроде этого под обложками. – WillD

2

Почему не ниже?

df1.except(df2) 
+0

Потому что это не выполняет XOR. Я искал все элементы НЕ на пересечении. Ваш код возвращает только элементы в d1, которые не находятся в пересечении. Мне также нужны те, что в d2, которые не находятся на пересечении. – WillD

1

Обратите внимание, что EXCEPT (или MINUS, который является просто псевдонимом для EXCEPT) отменяет результаты. Так что, если вы ожидаете, «кроме» установлен (разн вы упомянули) + «пересекаются» устанавливается равным первоначальному dataframe, рассмотреть этот запрос функции, которая держит дубликаты:

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

Как я там написал, «КРОМЕ ALL "может быть переписана в 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 
Смежные вопросы