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

如何在MultiIndex DataFrame的列第一层添加N、Count、Prop列?

Pandas透视表添加多层统计列(总数、计数、占比)

问题背景

现有代码生成的透视表仅包含各品牌在Shop1不同选项下的计数,需要扩展列结构,为每个Shop1选项添加总数(N)、计数(Count)、**占比(Prop)**三个维度的统计值,原尝试的MultiIndex.from_product方法无法实现目标结构。

完整解决方案代码

import pandas as pd

data = {
 'WholesalerID': {0: 121, 1: 121, 2: 42, 3: 42, 4: 54, 5: 43, 6: 432, 7: 4245, 8: 4245, 9: 4245, 10: 457},
 'Brand': {0: 'Vans', 1: 'Nike', 2: 'Nike', 3: 'Vans',4: 'Vans', 5: 'Nike', 6: 'Puma', 7: 'Vans', 8: 'Nike', 9: 'Puma', 10: 'Converse'},
 'Shop 1': {0: 'Yes', 1: 'No', 2: 'Yes', 3: 'Maybe', 4: 'Yes', 5: 'No', 6: 'Yes', 7: 'Yes', 8: 'Maybe', 9: 'Maybe', 10: 'No'}
}
df = pd.DataFrame.from_dict(data)

# 生成基础透视表(计数)
df = df.assign(count=1)
pivoted_df = pd.pivot_table(
    df,
    index=["Brand"],
    columns=["Shop 1"],
    values=["count"],
    aggfunc={"count": "count"},
    fill_value=0,
    margins=True,
    margins_name="N",
)

# 提取计数数据并计算总数、占比
count_df = pivoted_df['count'].copy()
# 计算每个品牌的总样本数N
count_df['N'] = df.groupby('Brand')['WholesalerID'].size()
# 合计行的N为总样本量
count_df.loc['N', 'N'] = len(df)
# 计算各选项占品牌总数的比例
prop_df = count_df[['Yes', 'No', 'Maybe']].div(count_df['N'], axis=0)

# 组合多层列索引:第一层为统计维度,第二层为Shop1选项
result = pd.concat([
    # 总数列:每个Shop1选项对应品牌的总样本数
    count_df[['Yes', 'No', 'Maybe']].apply(lambda _: count_df['N'], axis=0),
    # 计数列:原透视表的计数数据
    count_df[['Yes', 'No', 'Maybe']],
    # 占比列:计算得到的比例
    prop_df
], axis=1, keys=['总数', '计数', '占比'])

# 调整列顺序,让同一Shop1选项的三个统计值相邻
result = result.swaplevel(axis=1).sort_index(axis=1)

print(result)

代码说明

  1. 基础透视表生成:保留原代码逻辑,得到各品牌在Shop1不同选项下的计数数据,同时生成合计行。
  2. 总数计算:通过groupby统计每个品牌的总样本数,合计行的总数设为整个数据集的样本量。
  3. 占比计算:将各选项的计数除以对应品牌的总数,得到占比。
  4. 多层列构造:使用pd.concat的keys参数创建第一层列索引(总数、计数、占比),再通过swaplevel和sort_index调整列的排列顺序,使同一Shop1选项的三个统计值连续排列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:07:53