В этой статье мы рассмотрим различные типы соединений (JOIN), которые предлагает PySpark SQL, с их синтаксисом и простыми примерами.
Список соединений, предоставляемых PySpark SQL, следующий:
INNER JOIN
или простоJOIN
– внутреннее соединениеLEFT
– левое внешнее соединениеOUTER
JOINRIGHT
– правое внешнее соединениеOUTER
JOINOUTER
/FULL JOIN
– полное внешнее соединениеCROSS JOIN
– перекрестное (или декартово) произведениеLEFT ANTI JOIN
– левое антисоединениеLEFT
SEMI
JOIN
– левое полусоединениеSELF
JOIN
– соединение внутри одной таблицы
БЕСПЛАТНО СКАЧАТЬ КНИГИ в телеграм канале "Библиотека тестировщика"
INNER JOIN
Возвращает только те строки из обоих фреймов данных (dataframes), которые имеют совпадающие значения в обоих столбцах, указанных в качестве ключей объединения.
Синтаксис
df1.join(df2, df1['key'] == df2['key'], 'inner').show()
В приведенном выше примере
df1
иdf2
– это два объединяемых фрейма данных, аkey
– это столбец, который используется в качестве ключа объединения. Последний параметр,'inner'
, задает тип соединения, которое должно быть выполнено.
Пример
from pyspark.sql import SparkSession # Create a Spark session spark = SparkSession.builder.appName("InnerJoinExample").getOrCreate() # Create the first dataframe df1 = spark.createDataFrame([("A", 1), ("B", 2), ("C", 3)], ["letter", "number"]) # Create the second dataframe df2 = spark.createDataFrame([("A", 4), ("B", 5), ("D", 6)], ["letter", "value"]) # Perform the inner join inner_join = df1.join(df2, df1['letter'] == df2['letter'], "inner") # Show the result of the join inner_join.show() # Output: # +-----+------+-----+ # |letter|number|value| # +-----+------+-----+ # | A| 1| 4| # | B| 2| 5| # +-----+------+-----+
В данном примере создаются два фрейма данных,
df1
иdf2
, с колонкамиletter
иnumber
, иletter
иvalue
, соответственно. Внутреннее соединение выполняется междуdf1
иdf2
с использованием столбцав качестве ключа соединения. Результатом внутреннего соединения является новый фрейм данных, содержащий только те строки из
letter
df1
иdf2
где значения вletter
столбце совпадают. Результирующий фрейм данных содержит две строки для букв “A” и “B”, которые являются единственными буквами, присутствующими в обоих фреймах данных.
LEFT OUTER JOIN
Возвращает все строки из левого фрейма данных и совпадающие с ним строки из правого фрейма данных. Если в правом фрейме нет совпадающих значений, то возвращается null.
Синтаксис
df1.join(df2, df1['key'] == df2['key'], 'left').show()
(OR)
df1.join(df2, df1['key'] == df2['key'], 'leftouter').show()
В приведенном примере
df1
иdf2
– это два объединяемых фрейма данных, аkey
– это столбец, который используется в качестве ключа объединения. Последний параметр,'left'
, задает тип внешнего соединения.
Пример
Возьмем тот же набор данных, как и в предыдущем примере для внутреннего соединения:
# Perform the left outer join left_outer_join = df1.join(df2, df1['letter'] == df2['letter'], "left_outer") # Show the result of the join left_outer_join.show() # Output: # +-----+------+-----+ # |letter|number|value| # +-----+------+-----+ # | A| 1| 4| # | B| 2| 5| # | C| 3| null| # +-----+------+-----+
В данном примере создаются два фрейма данных,
df1
иdf2
, с колонкамиletter
иnumber
, иletter
иvalue
, соответственно. Междуdf1
иdf2
выполняется левое внешнее соединение с использованием столбцав качестве ключа объединения. Результатом левого внешнего соединения является новый фрейм данных, содержащий все строки из левого фрейма (
letter
df1
) и совпадающие строки из правого фрейма (df2
), в данном случае – это столбец .
RIGHT OUTER
JOIN
OUTER
JOINВозвращает все строки из правого фрейма данных и совпадающие строки из левого фрейма данных. Если в левом фрейме нет совпадающих значений, то возвращается null.
Синтаксис
df1.join(df2, df1['key'] == df2['key'], 'right').show()
(OR)
df1.join(df2, df1['key'] == df2['key'], 'rightouter').show()
В приведенном примере
df1
иdf2
– это два объединяемых фрейма данных, аkey
– это столбец, который используется в качестве ключа объединения. Последний параметр,'right'
, задает тип внешнего соединения, которое должно быть выполнено
Пример
Возьмем тот же набор данных, как и в первом примере для внутреннего соединения:
# Perform the right outer join right_outer_join = df1.join(df2, df1['letter'] == df2['letter'], "right_outer") # Show the result of the join right_outer_join.show() # Output: # +-----+------+-----+ # |letter|number|value| # +-----+------+-----+ # | A| 1| 4| # | B| 2| 5| # | D| null| 6| # +-----+------+-----+
В данном случае создаются два фрейма данных,
df1
иdf2
, с колонкамиletter
иnumber
, иletter
иvalue
, соответственно. Междуdf1
иdf2
выполняется правое внешнее соединение с использованием столбцаletter
в качестве ключа объединения. Результатом правого внешнего соединения является новый фрейм данных, содержащий все строки из правого фрейма (df2
) и совпадающие строки из левого фрейма (df1
). Если для строки из левого фрейма нет совпадений, то соответствующее значение в правом фрейме сохраняется, а столбцам из левого фрейма присваивается null значение.
OUTER
/ FULL JOIN
Возвращает все строки из обоих фреймов данных, включая совпадающие и не совпадающие строки. Если совпадающих значений нет, то результат будет содержать значение null вместо отсутствующих данных.
Синтаксис
df1.join(df2, df1['key'] == df2['key'], 'outer').show()
(OR)
df1.join(df2, df1['key'] == df2['key'], 'full').show()
(OR)
df1.join(df2, df1['key'] == df2['key'], 'fullouter').show()
В приведенном примере
df1
иdf2
– это два объединяемых фрейма данных, аkey
– это столбец, который используется в качестве ключа объединения. Последний параметр,'outer'
, задает тип внешнего соединения.
Пример
Используем тот же набор данных, как и в первом примере для внутреннего соединения:
# Perform the full outer join full_outer_join = df1.join(df2, df1['letter'] == df2['letter'], "full_outer") # Show the result of the join full_outer_join.show() # Output: # +-----+------+-----+ # |letter|number|value| # +-----+------+-----+ # | A| 1| 4| # | B| 2| 5| # | C| 3| null| # | D| null| 6| # +-----+------+-----+
В данном примере создаются два фрейма данных,
df1
иdf2
, с колонкамиletter
иnumber
, иletter
иvalue
, соответственно. Междуdf1
иdf2
выполняется полное внешнее объединение с использованием столбцаletter
в качестве ключа объединения. Результатом полного внешнего соединения является новый фрейм данных, содержащий все строки из обоих фреймов. Если строка в одном из них не совпадает, то соответствующее значение в другом фрейме сохраняется, а столбцам без совпадения присваивается null значение.
CROSS JOIN
Возвращает все возможные комбинации строк из обоих фреймов данных. Другими словами, берется каждая строка из одного фрейма данных и сопоставляется с каждой строкой в другом фрейме данных. В результате получается новый фрейм со всеми возможными комбинациями строк из двух входных фреймов данных.
Перекрестное соединение используется, когда мы хотим выполнить полное внешнее соединение, но более эффективным с точки зрения вычислений способом. Перекрестные соединения не рекомендуется использовать для больших наборов данных, поскольку они могут создавать очень большое количество записей, что приведет к проблемам с памятью и низкой производительности.
Синтаксис:
df1.crossJoin(df2).show()
В приведенном выше примере
df1
иdf2
– это два фрейма данных, которые объединяются с помощью функции'crossJoin'
.
Пример
from pyspark.sql import SparkSession # Create a Spark session spark = SparkSession.builder.appName("CrossJoinExample").getOrCreate() # Create the first dataframe df1 = spark.createDataFrame([("A", 1), ("B", 2), ("C", 3)], ["letter", "number"]) # Create the second dataframe df2 = spark.createDataFrame([("X", 4), ("Y", 5), ("Z", 6)], ["symbol", "value"]) # Perform the cross join cross_join = df1.crossJoin(df2) # Show the result of the join cross_join.show() # Output: # +-----+------+------+-----+ # |letter|number|symbol|value| # +-----+------+------+-----+ # | A| 1| X | 4 | # | A| 1| Y | 5 | # | A| 1| Z | 6 | # | B| 2| X | 4 | # | B| 2| Y | 5 | # | B| 2| Z | 6 | # | C| 3| X | 4 | # | C| 3| Y | 5 | # | C| 3| Z | 6 | # +-----+------+------+-----+
В данном примере создаются два фрейма данных,
df1
иdf2
, с колонкамиletter
иnumber
, иsymbol
иvalue
, соответственно. Междуdf1
иdf2
выполняется перекрестное соединение. Результатом перекрестного соединения является новый фрейм данных, содержащий все возможные комбинации строк из обоих фреймов. В результате такого типа объединения получается большое количество дублирующихся строк, поэтому использовать его следует с осторожностью.
LEFT ANTI JOIN
Левое антисоединение в PySpark SQL – это тип операции левого соединения, который возвращает только те строки из левого фрейма данных, которые не имеют соответствующих значений в правом фрейме. Оно используется для поиска строк в одном фрейме данных, которые не имеют соответствующих значений в другом.
Результатом левого антисоединения является фрейм данных, содержащий только те строки из левого фрейма, которые не имеют совпадающих значений в правом. Если строка из левого фрейма имеет совпадающие значения в правом фрейме, то она не будет включена в результат.
Синтаксис:
df1.join(df2, df1['key'] == df2['key'], 'left_anti').show()
В приведенном примере
df1
иdf2
– это два объединяемых фрейма данных, аkey
– это столбец, который используется в качестве ключа объединения. Последний параметр'left_anti'
указывает на то, что это левое антисоединение.
Пример
from pyspark.sql import SparkSession # Create a Spark session spark = SparkSession.builder.appName("LeftAntiJoinExample").getOrCreate() # Create the first dataframe df1 = spark.createDataFrame([("A", 1), ("B", 2), ("C", 3)], ["letter", "number"]) # Create the second dataframe df2 = spark.createDataFrame([("A", 4), ("B", 5)], ["letter", "value"]) # Perform the left anti join left_anti_join = df1.join(df2, df1['letter'] == df2['letter'], "left_anti") # Show the result of the join left_anti_join.show() # Output: # +-----+------+ # |letter|number| # +-----+------+ # | C| 3| # +-----+------+
В данном примере создаются два фрейма данных,
df1
иdf2
, с колонкамиletter
иnumber
, иletter
иvalue
, соответственно. Междуdf1
иdf2
столбцомв качестве ключа соединения выполняется левое антисоединение. Результатом левого антисоединения является новый фрейм данных, содержащий только те строки из первого фрейма (
letter
df1
), которые не совпадают ни с одной строкой во втором фрейме (df2
). Результат такого типа соединения включает только столбцы из первого фрейма, поскольку цель левого антисоединения – найти уникальные строки.
LEFT
SEMI
JOIN
Левое полусоединение в PySpark SQL – это тип операции присоединения, который возвращает только те столбцы из левого фрейма данных, которые имеют совпадающие значения в правом фрейме данных. Оно используется для поиска значений в одном фрейме, которые имеют соответствия в другом.
Результатом левого полусоединения является новый фрейм данных, содержащий только те столбцы из левого фрейма, которые имеют совпадающие значения в правом фрейме. Столбцы из правого фрейма данных в результат не включаются.
Синтаксис
df1.join(df2, df1['key'] == df2['key'], 'leftsemi').show()
В приведенном примере
df1
иdf2
– это два объединяемых фрейма данных, аkey
– это столбец, который используется в качестве ключа объединения. Последний параметр'leftsemi'
указывает на то, что это левое полусоединение.
Пример
from pyspark.sql import SparkSession # Create a Spark session spark = SparkSession.builder.appName("LeftSemiJoinExample").getOrCreate() # Create the first dataframe df1 = spark.createDataFrame([("A", 1), ("B", 2), ("C", 3)], ["letter", "number"]) # Create the second dataframe df2 = spark.createDataFrame([("A", 4), ("B", 5)], ["letter", "value"]) # Perform the left semi join left_semi_join = df1.join(df2, df1['letter'] == df2['letter'], "leftsemi") # Show the result of the join left_semi_join.show() # Output: # +-----+------+ # |letter|number| # +-----+------+ # | A| 1| # | B| 2| # +-----+------+
В данном примере создаются два фрейма данных,
df1
иdf2
, с колонкамиletter
иnumber
, иletter
иvalue
, соответственно. Междуdf1
иdf2
столбцомв качестве ключа соединения выполняется левое полусоединение. Результатом левого полусоединения является новый фрейм данных, содержащий только те столбцы первого фрейма (
letter
df1
), которые совпадают со строками второго фрейма (df2
). Результат этого типа объединения включает только столбцы из первого фрейма, поскольку целью левого полусоединения является поиск строк в первом фрейме, которые совпадают со строками во втором фрейме.
SELF
JOIN
Соединение внутри одной таблицы / самосоединение – это операция, при которой фрейм данных объединяется с самим собой. Она используется для сравнения значений в одном фрейме данных и возврата строк, соответствующих заданным критериям.
Например, самосоединение может быть использовано для поиска всех пар строк в фрейме данных, в которых значения в двух столбцах равны. В результате будет получен новый фрейм данных, содержащий только те строки, которые удовлетворяют заданным критериям.
Синтаксис
df.alias("df1").join(df.alias("df2"), df1['key'] == df2['key']).show()
В приведенном примере
df
– это фрейм данных, который объединяется сам с собой, аkey
– это столбец, который используется в качестве ключа объединения. Для выполнения самосоединения фрейм данных должен иметь алиасы (alias) с двумя разными именами, в данном случаеdf1
иdf2
.
Пример
from pyspark.sql import SparkSession # Create a Spark session spark = SparkSession.builder.appName("SelfJoinExample").getOrCreate() # Create a dataframe df = spark.createDataFrame([("A", 1), ("B", 2), ("C", 3)], ["letter", "number"]) # Perform the self join self_join = df.alias("df1").join(df.alias("df2"), df["letter"] == df["letter"]) # Show the result of the join self_join.show() # Output: # +-----+------+-----+------+ # |letter|number|letter|number| # +-----+------+-----+------+ # | A| 1| A| 1| # | B| 2| B| 2| # | C| 3| C| 3| # +-----+------+-----+------+
В данном примере создается один фрейм данных
df
с колонкамиletter
иnumber
. В качестве ключа соединения используется столбец. Результатом самосоединения является новый фрейм данных, содержащий все комбинации строк между двумя экземплярами исходного фрейма данных. Для того чтобы различать два экземпляра исходного фрейма данных при соединении, им присваиваются уникальные алиасы.
letter
Заключение
В этой статье мы подробно разобрали различные типы соединений таблиц в PySpark SQL на простых примерах с Python. Если у вас остались какие-либо вопросы, пишите их в комментариях.
Перевод статьи «Exploring the Different Join Types in Spark SQL: A Step-by-Step Guide».