Присоедините два кадра данных, выберите все столбцы из одного и нескольких столбцов из другого

Скажем, у меня есть световой кадр df1 с несколькими столбцами (среди которых идентификатор столбца) и фрейм данных df2 с двумя столбцами: "id" и "other".

Есть ли способ репликации следующей команды

sqlContext.sql("SELECT df1.*, df2.other FROM df1 JOIN df2 ON df1.id = df2.id")

используя только функции pyspark, такие как join(), select() и т.п.?

Мне нужно реализовать это объединение в функции, и я не хочу, чтобы был вынужден использовать sqlContext в качестве параметра функции.

Спасибо!

Ответы

Ответ 1

Не уверен, что самый эффективный способ, но это сработало для меня:

from pyspark.sql.functions import col

df1.alias('a').join(df2.alias('b'),col('b.id') = col('a.id')).select([col('a.'+xx) for xx in a.columns] + [col('b.other1'),col('b.other2')])

Трюк находится в:

[col('a.'+xx) for xx in a.columns] : all columns in a

[col('b.other1'),col('b.other2')] : some columns of b

Ответ 2

Asterisk (*) работает с псевдонимом. Пример:

from pyspark.sql.functions import *

df1 = df.alias('df1')
df2 = df.alias('df2')

df1.join(df2, df1.id == df2.id).select('df1.*')

Ответ 3

Вот решение, которое не требует контекста SQL, но поддерживает метаданные DataFrame.

a = sc.parallelize([['a', 'foo'], ['b', 'hem'], ['c', 'haw']]).toDF(['a_id', 'extra'])
b = sc.parallelize([['p1', 'a'], ['p2', 'b'], ['p3', 'c']]).toDF(["other", "b_id"])

c = a.join(b, a.a_id == b.b_id)

Тогда c.show() дает:

+----+-----+-----+----+
|a_id|extra|other|b_id|
+----+-----+-----+----+
|   a|  foo|   p1|   a|
|   b|  hem|   p2|   b|
|   c|  haw|   p3|   c|
+----+-----+-----+----+