Подтвердить что ты не робот

Как получить разницу между двумя DataFrames?

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

df1.except(df2)

Ответ 3

Обратите внимание, что EXCEPT (или MINUS, который является просто псевдонимом для EXCEPT) отменяет результаты. Поэтому, если вы ожидаете, что параметр "except" (упомянутый вами diff) + "intersect" установлен равным исходному фреймворку данных, рассмотрите этот запрос функции, который хранит дубликаты:

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

Как я там писал, "EXCEPT 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

Ответ 4

Если вы ищете решение Pyspark, вам следует использовать subtract() docs.

Кроме того, unionAll устарело в 2.0, вместо этого используйте union().

df1.union(df2).subtract(df1.intersect(df2))

Ответ 5

Я думаю, что было бы эффективнее использовать left join и затем отфильтровывать пустые значения.

df1.join(df2, Seq("some_join_key", "some_other_join_key"),"left")
.where(col("column_just_present_in_df2").isNull)