Pandas分组统计Score_1均值、Level占比及堆叠横条图绘制
报错根因说明
你之前调用unstack('Level')抛出KeyError,本质是分组维度不匹配:你编写的df.groupby('Category')["Score_1"].mean()整个分组结果的索引只有Category一个层级,完全没有将Level纳入分组维度,自然找不到名为Level的索引层级,因此触发报错。
另外你现有计算Mean的代码存在笔误:第三行Df_90=D_90.reset_index()中变量名书写错误,前面定义的对象是Df_90,这里误写为D_90,直接运行也会触发NameError。
目标数据集分步实现
整个计算拆成两个独立逻辑块,最后按Category主键合并即可,避免分组维度混乱:
- 计算分组均值列
按Category分组计算Score_1的算术平均,作为结果表的Mean列:mean_df = df.groupby('Category', as_index=False)["Score_1"].mean().rename(columns={"Score_1": "Mean"}) - 计算Level占比并转置为独立列
先同时按Category、Level两个维度分组统计记录数,再按Category组内做归一化得到百分比,最后把Level维度unstack为列:# 双维度统计每组的记录条数 level_count = df.groupby(['Category', 'Level']).size() # 按Category组内计算占比,乘以100转为百分比数值 level_pct = level_count.groupby(level=0).apply(lambda x: x / x.sum() * 100) # 把Level维度unstack为列,无对应记录的占比补0,列名加上(%)后缀和示例格式对齐 level_pct_df = level_pct.unstack('Level', fill_value=0).add_suffix('(%)').reset_index() - 合并生成最终目标表
把均值表和占比表按Category主键做内连接,即可得到和示例结构完全一致的数据集,可按需将百分比值保留2位小数:result_df = mean_df.merge(level_pct_df, on='Category') # 格式化百分比保留2位小数 pct_cols = [col for col in result_df.columns if col.endswith('(%)')] result_df[pct_cols] = result_df[pct_cols].round(2)
水平堆叠条形图实现
注意绘图规则:单根横向条形的总长度等于对应Category的Mean值,内部分段的宽度比例等于该类别的Level占比,不能直接用百分比值作为条形长度。需要先把各Level的百分比值换算为实际分段长度(计算公式:分段长度 = 对应Level的百分比 * 同Category的Mean / 100),再做堆叠绘图:
import matplotlib.pyplot as plt # 索引设置为Category,将百分比换算为实际条形分段长度 plot_base = result_df.set_index('Category') for col in pct_cols: plot_base[col] = plot_base[col] * plot_base['Mean'] / 100 # 绘制水平堆叠条形图 plot_base[pct_cols].plot( kind='barh', stacked=True, figsize=(8, 4), xlabel='Category', ylabel='Score_1均值' ) # 调整图例位置避免遮挡图形 plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left') plt.tight_layout() plt.show()
以上逻辑中,
fill_value=0的配置会自动为未出现的Level占比补0,不会出现空值导致的绘图断裂问题。
内容的提问来源于stack exchange,提问作者viji
相关产品推荐
相关产品推荐

