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

如何在PySpark DataFrame中按列合并重复行并求和

PySpark 合并重复行并对指定列求和

问题说明

现有包含重复行的PySpark DataFrame,需基于Deal_ID列合并重复项,同时对In_Progress和Deal_Total列求和,得到目标结果。

当前数据表

Deal_ID Title   Customer    In_Progress Deal_Total
30      Deal 1  Client A    350         900
30      Deal 1  Client A    360         850
50      Deal 2  Client B    30          50
30      Deal 1  Client A    125         200
30      Deal 1  Client A    90          100
10      Deal 3  Client C    32          121

预期结果

Deal_ID Title   Customer    In_Progress Deal_Total
30      Deal 1  Client A    925         2050
50      Deal 2  Client B    30          50
10      Deal 3  Client C    32          121

现有代码问题

你尝试的when+count写法存在两处核心问题:

  • 聚合函数count不能直接在when中做行级判断,必须配合分组操作使用
  • F.sum(...) && F.sum(...)语法错误,&&是布尔逻辑运算符,无法用来同时指定多个求和列

正确解决方案

直接使用groupBy分组,配合agg完成多列求和即可。由于同一Deal_ID对应的Title和Customer值一致,可通过聚合函数保留对应值:

from pyspark.sql import functions as F

# 假设你的DataFrame名为df
result_df = df.groupBy("Deal_ID", "Title", "Customer") \
              .agg(
                  F.sum("In_Progress").alias("In_Progress"),
                  F.sum("Deal_Total").alias("Deal_Total")
              ) \
              .orderBy("Deal_ID")

result_df.show()

代码解释

  1. groupBy("Deal_ID", "Title", "Customer"):将这三列作为分组依据,确保同一Deal_ID对应的Title和Customer值能正确保留
  2. agg(...):对指定列执行求和操作,用alias保持列名与原表一致
  3. orderBy("Deal_ID"):可选操作,让结果按Deal_ID排序,与预期格式匹配

若不确定Title和Customer是否始终与Deal_ID一一对应,也可仅按Deal_ID分组,再用first()获取这两列的值:

result_df = df.groupBy("Deal_ID") \
              .agg(
                  F.first("Title").alias("Title"),
                  F.first("Customer").alias("Customer"),
                  F.sum("In_Progress").alias("In_Progress"),
                  F.sum("Deal_Total").alias("Deal_Total")
              ) \
              .orderBy("Deal_ID")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 11:45:31