连接两个数据帧,其中连接键不同,只有 select 一些列
Join two DataFrames where the join key is different and only select some columns
我想做的是:
使用各自的 id
列 a_id
和 b_id
连接两个 DataFrame A
和 B
。我想 select 来自 A
的所有列和来自 B
的两个特定列
我用不同的引号尝试了类似下面的内容,但仍然无法正常工作。我觉得在pyspark中,应该有一个简单的方法来做到这一点。
A_B = A.join(B, A.id == B.id).select(A.*, B.b1, B.b2)
我知道你可以写
A_B = sqlContext.sql("SELECT A.*, B.b1, B.b2 FROM A JOIN B ON A.a_id = B.b_id")
这样做,但我更想像上面的伪代码那样做。
试试这个解决方案:
A_B = A.join(B,col('B.id') == col('A.id')).select([col('A.'+xx) for xx in A.columns]
+ [col('B.other1'),col('B.other2')])
SELECT
中的以下几行起到了从 A 中选择所有列和从 Table B 中选择 2 列的把戏。
[col('a.'+xx) for xx in a.columns] : all columns in a
[col('b.other1'),col('b.other2')] : some columns of b
你的伪代码基本正确。如果 id
列存在于两个 DataFrame 中,这个稍微修改的版本将起作用:
A_B = A.join(B, on="id").select("A.*", "B.b1", "B.b2")
来自 pyspark.sql.DataFrame.join()
的文档:
If on
is a string or a list of strings indicating the name of the join
column(s), the column(s) must exist on both sides, and this performs
an equi-join.
由于key不同,你可以直接使用withColumn()
(或withColumnRenamed()
)在两个DataFrame中创建一个同名的列:
A_B = A.withColumn("id", col("a_id")).join(B.withColumn("id", col("b_id")), on="id")\
.select("A.*", "B.b1", "B.b2")
如果你的 DataFrame 有很长很复杂的名字,你也可以使用 alias()
让事情变得简单:
A_B = long_data_frame_name1.alias("A").withColumn("id", col("a_id"))\
.join(long_data_frame_name2.alias("B").withColumn("id", col("b_id")), on="id")\
.select("A.*", "B.b1", "B.b2")
我认为更简单的解决方案是将 table A 和 table B 与您想要的选定列连接起来。这是执行此操作的示例代码:
joined_tables = table_A.join(table_B.select('col1', 'col2', 'col3'), ['id'])
上面的代码连接了 table_A 中的所有列和 "col1"、"col2"、"col3" 中的 table_B 列。
我想做的是:
使用各自的 id
列 a_id
和 b_id
连接两个 DataFrame A
和 B
。我想 select 来自 A
的所有列和来自 B
我用不同的引号尝试了类似下面的内容,但仍然无法正常工作。我觉得在pyspark中,应该有一个简单的方法来做到这一点。
A_B = A.join(B, A.id == B.id).select(A.*, B.b1, B.b2)
我知道你可以写
A_B = sqlContext.sql("SELECT A.*, B.b1, B.b2 FROM A JOIN B ON A.a_id = B.b_id")
这样做,但我更想像上面的伪代码那样做。
试试这个解决方案:
A_B = A.join(B,col('B.id') == col('A.id')).select([col('A.'+xx) for xx in A.columns]
+ [col('B.other1'),col('B.other2')])
SELECT
中的以下几行起到了从 A 中选择所有列和从 Table B 中选择 2 列的把戏。
[col('a.'+xx) for xx in a.columns] : all columns in a
[col('b.other1'),col('b.other2')] : some columns of b
你的伪代码基本正确。如果 id
列存在于两个 DataFrame 中,这个稍微修改的版本将起作用:
A_B = A.join(B, on="id").select("A.*", "B.b1", "B.b2")
来自 pyspark.sql.DataFrame.join()
的文档:
If
on
is a string or a list of strings indicating the name of the join column(s), the column(s) must exist on both sides, and this performs an equi-join.
由于key不同,你可以直接使用withColumn()
(或withColumnRenamed()
)在两个DataFrame中创建一个同名的列:
A_B = A.withColumn("id", col("a_id")).join(B.withColumn("id", col("b_id")), on="id")\
.select("A.*", "B.b1", "B.b2")
如果你的 DataFrame 有很长很复杂的名字,你也可以使用 alias()
让事情变得简单:
A_B = long_data_frame_name1.alias("A").withColumn("id", col("a_id"))\
.join(long_data_frame_name2.alias("B").withColumn("id", col("b_id")), on="id")\
.select("A.*", "B.b1", "B.b2")
我认为更简单的解决方案是将 table A 和 table B 与您想要的选定列连接起来。这是执行此操作的示例代码:
joined_tables = table_A.join(table_B.select('col1', 'col2', 'col3'), ['id'])
上面的代码连接了 table_A 中的所有列和 "col1"、"col2"、"col3" 中的 table_B 列。