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

Самый чистый, самый эффективный синтаксис для самоподключения DataFrame в Spark

В стандартном SQL, когда вы присоединяете таблицу к себе, вы можете создавать псевдонимы для таблиц для отслеживания тех столбцов, на которые вы ссылаетесь:

SELECT a.column_name, b.column_name...
FROM table1 a, table1 b
WHERE a.common_field = b.common_field;

Есть два способа, которыми я могу думать, чтобы достичь того же, используя Spark DataFrame API:

Решение №1: переименовать столбцы

Для ответа на этот вопрос существует несколько различных методов. Это просто переименовывает все столбцы с определенным суффиксом:

df.toDF(df.columns.map(_ + "_R"):_*)

Например, вы можете:

df.join(df.toDF(df.columns.map(_ + "_R"):_*), $"common_field" === $"common_field_R")

Решение № 2: Скопируйте ссылку на DataFrame

Еще одно простое решение - просто сделать это:

val df: DataFrame = ....
val df_right = df

df.join(df_right, df("common_field") === df_right("common_field"))

Оба этих решения работают, и я мог видеть, что каждый из них полезен в определенных ситуациях. Существуют ли какие-либо внутренние различия между этими двумя, о которых я должен знать?

4b9b3361

Ответ 1

Существует по крайней мере два разных способа, с помощью которых вы можете подойти либо путем сглаживания:

df.as("df1").join(df.as("df2"), $"df1.foo" === $"df2.foo")

или с использованием основанного на имени равенства:

// Note that it will result in ambiguous column names
// so using aliases here could be a good idea as well.
// df.as("df1").join(df.as("df2"), Seq("foo"))

df.join(df, Seq("foo"))  

В общем переименование столбцов, в то время как самый уродливый, является самой безопасной практикой во всех версиях. Было несколько ошибок, связанных с разрешением столбца (мы нашли один на SO не так давно), и некоторые детали могут различаться между синтаксическими анализаторами (HiveContext/standard SQLContext), если вы используете сырые выражения.

Лично я предпочитаю использовать псевдонимы, потому что их сходство с идиоматическим SQL и возможность использования вне области конкретных объектов DataFrame.

Что касается производительности, если вы не заинтересованы в обработке в реальном времени, не должно быть никаких различий в производительности. Все они должны генерировать один и тот же план выполнения.