web-dev-qa-db-ja.com

2つのデータフレームを結合し、一方からすべての列を選択し、もう一方からいくつかの列を選択します

sparkデータフレームdf1があり、いくつかの列(列 'id')と2つの列 'id'および 'other'のデータフレームdf2があるとします。

次のコマンドを複製する方法はありますか

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

join()、select()などのpyspark関数のみを使用して?

この結合を関数に実装する必要があり、関数パラメーターとしてsqlContextを強制する必要はありません。

ありがとう!

47
Francesco Sambo

最も効率的な方法かどうかはわかりませんが、これは私のために働いた:

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
47
Pablo Estevez

アスタリスク(*)はエイリアスで機能します。例:

from pyspark.sql.functions import *

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

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

エイリアスを使用しない場合

df1.join(df2, df1.id == df2.id).select(df1["*"],df2["other"])
12

以下は、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|
+----+-----+-----+----+
9
Katya Handler

重複するb_idを削除します

c = a.join(b, a.a_id == b.b_id).drop(b.b_id)
3
Selvaraj S.
0
Erica

エラーが発生しました:推奨コードを使用して「見つかりません」:

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')])

a.columnsdf1.columnsに変更しましたが、うまくいきました。

0
filip stepniak