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

如何在pandas中实现DataFrame逆groupby宽转长并添加累计行?

Pandas宽表转长表并新增累计行实现方案

核心思路

整个操作分三步完成:

  • 把按列存储的分阶段数据从宽表转为行存储的长表格式
  • 按项目ID计算所有阶段的天数总和,生成cumulative类型的记录
  • 拼接两部分数据并调整排序,得到最终结果

完整可运行代码

import pandas as pd

# 构造原始示例数据
df = pd.DataFrame({
    "project id": [112, 113],
    "phase 1": [29, 36],
    "phase 2": [157, 121],
    "phase 3": [213, 23]
})

# 宽表转长表,自动识别所有phase开头的列
long_df = df.melt(
    id_vars="project id",
    value_vars=df.filter(like="phase").columns,
    var_name="phase",
    value_name="days"
)
# 提取phase列的数字编号
long_df["phase"] = long_df["phase"].str.replace("phase ", "", regex=False)

# 生成每个项目的累计天数字段
cumulative_df = df[["project id"]].copy()
cumulative_df["phase"] = "cumulative"
# 对所有phase列横向求和得到总天数
cumulative_df["days"] = df.filter(like="phase").sum(axis=1)

# 拼接数据并调整排序
final_df = pd.concat([long_df, cumulative_df], ignore_index=True)
# 增加临时排序键,保证每个项目下阶段1/2/3在前,累计值在最后
final_df["sort_tmp"] = final_df["phase"].apply(lambda x: int(x) if x.isdigit() else 99)
final_df = final_df.sort_values(
    by=["project id", "sort_tmp"]
).drop(columns="sort_tmp").reset_index(drop=True)

运行结果

执行print(final_df)即可得到目标格式的数据集:

project id       phase  days
0         112           1    29
1         112           2   157
2         112           3   213
3         112  cumulative   399
4         113           1    36
5         113           2   121
6         113           3    23
7         113  cumulative   180

扩展说明

如果后续新增phase4、phase5等更多阶段列,无需修改核心逻辑,代码会自动识别所有带phase前缀的列完成转换和求和。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 11:24:22