Как вы выполняете базовые объединения двух таблиц RDD в Spark с помощью Python?

Как бы вы выполняли базовые объединения в Spark с помощью python? В R вы можете использовать merg() для этого. Что такое синтаксис с использованием python для искры для:

  • Внутренняя регистрация
  • Левая внешняя связь
  • Cross Join

С двумя таблицами (RDD) с одним столбцом в каждом, у которого есть общий ключ.

RDD(1):(key,U)
RDD(2):(key,V)

Я думаю, что внутреннее соединение выглядит примерно так:

rdd1.join(rdd2).map(case (key, u, v) => (key, ls ++ rs));

Это правильно? Я искал в Интернете и не могу найти хороший пример объединений. Спасибо заранее.

Ответ 1

Это можно сделать либо с помощью PairRDDFunctions, либо с помощью Spark Data Frames. Поскольку операции с фреймами данных извлекаются из Catalyst Optimizer, второй вариант стоит рассмотреть.

Предполагая, что ваши данные выглядят следующим образом:

rdd1 =  sc.parallelize([("foo", 1), ("bar", 2), ("baz", 3)])
rdd2 =  sc.parallelize([("foo", 4), ("bar", 5), ("bar", 6)])

С PairRDD:

Внутреннее соединение:

rdd1.join(rdd2)

Левое внешнее соединение:

rdd1.leftOuterJoin(rdd2)

Декартово произведение (не требует RDD[(T, U)]):

rdd1.cartesian(rdd2)

Широковещательное соединение (не требует RDD[(T, U)]):

Наконец, существует cogroup, который не имеет прямого SQL-эквивалента, но может быть полезен в некоторых ситуациях:

cogrouped = rdd1.cogroup(rdd2)

cogrouped.mapValues(lambda x: (list(x[0]), list(x[1]))).collect()
## [('foo', ([1], [4])), ('bar', ([2], [5, 6])), ('baz', ([3], []))]

С помощью Spark Data Frames

Вы можете использовать SQL DSL или выполнить необработанный SQL с помощью sqlContext.sql.

df1 = spark.createDataFrame(rdd1, ('k', 'v1'))
df2 = spark.createDataFrame(rdd2, ('k', 'v2'))

# Register temporary tables to be able to use sqlContext.sql
df1.createTempView('df1')
df2.createTempView('df2')

Внутреннее соединение:

# inner is a default value so it could be omitted
df1.join(df2, df1.k == df2.k, how='inner') 
spark.sql('SELECT * FROM df1 JOIN df2 ON df1.k = df2.k')

Левое внешнее соединение:

df1.join(df2, df1.k == df2.k, how='left_outer')
spark.sql('SELECT * FROM df1 LEFT OUTER JOIN df2 ON df1.k = df2.k')

Перекрестное соединение (явное перекрестное соединение или изменения конфигурации требуются в Spark. 2.0 - spark.sql.crossJoin.enabled для Spark 2.x):

df1.crossJoin(df2)
spark.sql('SELECT * FROM df1 CROSS JOIN df2')

df1.join(df2)
sqlContext.sql('SELECT * FROM df JOIN df2')

Так как 1.6 (1.5 в Scala), каждый из них может быть объединен с функцией broadcast:

from pyspark.sql.functions import broadcast

df1.join(broadcast(df2), df1.k == df2.k)

для выполнения широковещательного соединения. См. Также Почему мой BroadcastHashJoin медленнее, чем ShuffledHashJoin в Spark