
本文介绍如何在 pandas 中为已通过 `unstack()` 展开的多级索引 dataframe 快速添加按行求和的总计列,解决因索引结构错位导致的赋值失败问题,并提供简洁可靠的实现方案。
当你对分组计数结果调用 .unstack() 后,会得到一个以原始分组列为列、以剩余层级为行索引的二维表格(如 under_30 为行索引,churn_label 的 No/Yes 为列)。此时若想添加“Total”列,必须确保新列与当前 DataFrame 的行索引严格对齐——而原代码中 data_df["customer_id"].unstack().sum() 返回的是一个与列名对齐的 Series(索引为 ['No', 'Yes']),无法直接赋值给行索引为 ('No', 'Yes') 的 data_df,导致全为 NaN。
正确做法是:先构建结构清晰的 unstacked DataFrame,再使用 sum(axis=1) 沿行方向求和,Pandas 会自动按行索引对齐:
# 正确步骤:先 groupby + size + unstack,再按行求和 data_df = customer_churn_df.groupby(["under_30", "churn_label"]).size().unstack(fill_value=0) data_df["Total"] = data_df.sum(axis=1) # 自动对齐 under_30 索引
输出效果如下:
churn_label No Yes Total under_30 No 4077 1564 5641 Yes 1097 304 1401
✅ 关键要点:
- 使用 .size() 替代 .count() 可避免空值干扰,返回标量计数;
- fill_value=0 确保缺失组合(如某 under_30 值下无 churn_label="Yes")填充为 0,使 sum() 结果准确;
- axis=1 表示对每一行的所有数值列求和,结果天然继承原 DataFrame 的行索引;
- 列名可自由命名(如 "Total"),无需额外重命名操作。
⚠️ 注意:切勿在 unstack 后再尝试对原始分组列(如 "customer_id")重复 unstack 或跨层级求和——这会破坏索引一致性。始终让聚合、展开、汇总三步顺序清晰、索引可控。










