如何对Pandas DataFrame分组并转宽表,计算性别加权占比?
解决方法
你可以通过分组求和、计算组内占比和数据重塑三个步骤实现需求,以下是具体代码和说明:
1. 准备示例数据
首先构造你提供的DataFrame:
import pandas as pd data = { 'Category': ['Food', 'Food', 'Beverage', 'Beverage', 'Beverage', 'Food'], 'Detail': ['Apple', 'Apple', 'Milk', 'Milk', 'Milk', 'Banana'], 'Gender': ['Female', 'Male', 'Female', 'Male', 'Male', 'Female'], 'Weight': [30, 40, 10, 5, 20, 50] } df = pd.DataFrame(data)
2. 方法一:分步实现
步骤1:分组计算各性别Weight总和
按Category、Detail、Gender三级分组,统计每组的Weight总和:
grouped_sum = df.groupby(['Category', 'Detail', 'Gender'])['Weight'].sum().reset_index()
此时grouped_sum的结果:
| Category | Detail | Gender | Weight |
|---|---|---|---|
| Beverage | Milk | Female | 10 |
| Beverage | Milk | Male | 25 |
| Food | Apple | Female | 30 |
| Food | Apple | Male | 40 |
| Food | Banana | Female | 50 |
步骤2:计算组内占比
通过transform获取每个Category+Detail组的总Weight,再计算各性别占比:
# 计算每组总Weight grouped_sum['total_weight'] = grouped_sum.groupby(['Category', 'Detail'])['Weight'].transform('sum') # 计算占比并保留两位小数 grouped_sum['percentage'] = (grouped_sum['Weight'] / grouped_sum['total_weight']).round(2)
步骤3:重塑为宽格式
用pivot将长格式转宽格式,缺失的性别(如Banana的Male)填充为0,再格式化为百分比字符串:
result = grouped_sum.pivot( index=['Category', 'Detail'], columns='Gender', values='percentage' ).fillna(0) # 转换为带%的字符串 result = result.applymap(lambda x: f"{int(x*100)}%") # 重置索引,将分组列变回普通列 result = result.reset_index()
3. 方法二:用pivot_table一步简化
直接使用pivot_table完成分组求和和宽格式转换,再计算占比:
# 先得到宽格式的Weight总和,缺失值填充为0 pivot_df = df.pivot_table( index=['Category', 'Detail'], columns='Gender', values='Weight', aggfunc='sum', fill_value=0 ) # 计算每行总Weight,再求各性别占比并格式化 row_totals = pivot_df.sum(axis=1) pivot_df['Female'] = (pivot_df['Female'] / row_totals).round(2).apply(lambda x: f"{int(x*100)}%") pivot_df['Male'] = (pivot_df['Male'] / row_totals).round(2).apply(lambda x: f"{int(x*100)}%") # 重置索引 pivot_df = pivot_df.reset_index()
最终两种方法都会得到你需要的结果:
| Category | Detail | Female | Male |
|---|---|---|---|
| Beverage | Milk | 29% | 71% |
| Food | Apple | 43% | 57% |
| Food | Banana | 100% | 0% |
内容的提问来源于stack exchange,提问作者csarvf_01
相关产品推荐
相关产品推荐

