You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何横向拼接列不同但行数相同的多个PySpark DataFrame?

问题

需要拼接2个或多个列不同但行数相同的PySpark DataFrame(类似Pandas中pd.concat设置axis=1的横向拼接效果)。

假设有以下DataFrame:

spark = SparkSession.builder.getOrCreate()
df1 = spark.createDataFrame([[1, 1], [2, 2]], ['a', 'b'])
df2 = spark.createDataFrame([[3, 333], [4, 444]], ['c', 'd'])
df3 = spark.createDataFrame([[555, 5], [666, 6]], ['e', 'f'])

期望得到的最终DataFrame(行数不变,列合并)如下:

df_final = spark.createDataFrame([[1, 1, 3, 333, 555, 5], [2, 2, 4, 444, 666, 6]], ['a', 'b','c', 'd','e', 'f'])

尝试了以下代码:

df_final = df1.join(df2).join(df3)

但得到了大量重复数据(实际是笛卡尔积导致的行数爆炸),请问该如何解决?

解决方案

直接用join且不指定关联条件时,Spark会执行笛卡尔积:每个DataFrame的行与其他所有DataFrame的行两两组合,行数变成各df行数的乘积(比如3个2行的df会得到8行),这显然不是想要的横向拼接效果。

要实现类似pd.concat(axis=1)的横向拼接,核心是给每个DataFrame添加行号列,通过行号关联对应位置的行,具体步骤如下:

  1. 导入所需函数:
from pyspark.sql import functions as F
from pyspark.sql.window import Window
  1. 给每个DataFrame添加自增行号:
# 定义窗口,若需要指定行顺序,可在orderBy中添加对应列(比如df1.orderBy("a"))
window = Window.orderBy(F.lit(1))

df1_with_idx = df1.withColumn("row_idx", F.row_number().over(window))
df2_with_idx = df2.withColumn("row_idx", F.row_number().over(window))
df3_with_idx = df3.withColumn("row_idx", F.row_number().over(window))
  1. 按行号关联所有DataFrame,最后删除行号列:
df_final = df1_with_idx.join(df2_with_idx, on="row_idx", how="inner")\
                      .join(df3_with_idx, on="row_idx", how="inner")\
                      .drop("row_idx")
  1. 查看结果:
df_final.show()

输出:

+---+---+---+---+---+---+
|  a|  b|  c|  d|  e|  f|
+---+---+---+---+---+---+
|  1|  1|  3|333|555|  5|
|  2|  2|  4|444|666|  6|
+---+---+---+---+---+---+

关键注意点

  • 如果DataFrame有明确的排序逻辑,必须在Window.orderBy()中指定对应列,避免行号生成顺序出错(比如Window.orderBy("a")让df1按a列排序生成行号)。
  • 确保所有DataFrame行数完全一致,用inner join会丢弃行数不匹配的行;若要保留所有行,可改用outer join,但不匹配的位置会出现null值。

内容的提问来源于stack exchange,提问作者user139442

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 02:31:04