Pandas如何按分组计算分类值的组内百分比
Pandas分组计算类别占比实现方案
你用groupby().size()拿到计数结果后,只需要补充按组归一化的逻辑即可得到百分比,下面给两种可直接运行的实现方式:
方法1:最简写法,直接调用value_counts归一化参数
pandas的value_counts方法原生支持归一化计算占比,不需要手动算除法,代码最简洁:
import pandas as pd # 构造示例数据源 df = pd.DataFrame({ 'id': [1,1,1,2,3,3], 'value_type': ['b','a','a','a','a','b'] }) # 核心计算逻辑 result = df.groupby('id')['value_type']\ .value_counts(normalize=True)\ .reset_index(name='perc')\ .round(2) # 若需要匹配示例中id=1时b在前的顺序,加一行排序即可 result = result.sort_values(by=['id', 'value_type'], ascending=[True, False])
运行后打印result输出如下,和你预期结果完全一致:
id value_type perc 1 1 b 0.33 0 1 a 0.67 2 2 a 1.00 4 3 b 0.50 3 3 a 0.50
注:0.67和你示例里的0.66是四舍五入精度差异,如果你需要向下截断两位小数,可以把round(2)换成自定义取整逻辑,常规分析场景下round的结果精度足够。
方法2:基于你已写的size()逻辑改造
如果你已经用groupby().size()拿到了分组计数结果,不需要推倒重写,通过transform匹配每组总条数做除法即可:
# 你之前已经拿到的计数结果 count_df = df.groupby(['id', 'value_type']).size().reset_index(name='cnt') # 给每一行匹配所属id组的总样本量 count_df['group_total'] = count_df.groupby('id')['cnt'].transform('sum') # 计算占比 count_df['perc'] = (count_df['cnt'] / count_df['group_total']).round(2) # 筛选需要的列得到最终结果 result = count_df[['id', 'value_type', 'perc']]
补充说明
- 如果需要输出百分比格式(比如33%、66%),可以把占比计算行替换为
count_df['perc'] = (count_df['cnt'] / count_df['group_total']).apply(lambda x: f"{x*100:.0f}%") transform的作用是把分组聚合后的结果按原数据索引对齐返回,不会改变原表的行数,非常适合分组后给每行添加组级聚合值的场景
内容的提问来源于stack exchange,提问作者gh1222
相关产品推荐
相关产品推荐

