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

如何在Pandas中按列值分组并计算各标签占比聚合结果

解决Pandas按性别计算多列标签占比的问题

问题描述

现有如下结构的Pandas DataFrame:

id    gender  column_1  column_2  column_3  column_n
10      male     a          b         a           b
10      female   b          c         b           c
10      male     c          c         a           a
10      male     b          a         a           b

需要生成按id和column_name分组,统计不同性别下各标签(a/b/c)的占比(百分比,保留1位小数),期望输出如下:

id    column_name     male_%_a  male_%_b   male_%_c   female_%_a  female_%_b   female_%_c
10    column_1           33.3       33.3       33.3       0            100        0
10    column_2           33.3       33.3       33.3       0             0        100
10    column_3           100        0           0         0            100        0
10    column_n           33.3      66.7         0         0             0        100

要求适配任意数量的column_*列,DataFrame始终包含id和gender列。

解决方案

通过数据重塑+分组统计+格式调整的组合操作即可实现,步骤如下:

1. 重塑数据格式

用melt将所有column_*列转为行结构,保留id和gender作为标识列,把宽表转成便于统计的窄表:

melted_df = df.melt(id_vars=['id', 'gender'], var_name='column_name', value_name='label')

2. 计算分组标签占比

按id、gender、column_name、label分组统计计数,再计算每个标签在对应分组内的占比,转为百分比并保留1位小数:

# 统计每个分组内各标签的出现次数
counts = melted_df.groupby(['id', 'gender', 'column_name', 'label']).size().unstack(fill_value=0)
# 计算占比并转为百分比格式
percentages = (counts.div(counts.sum(axis=1), axis=0) * 100).round(1)

3. 调整列名与输出格式

将性别和标签合并为指定格式的列名,再重置索引恢复id和column_name为普通列:

# 重命名列,统一为「性别_%_标签」格式
percentages.columns = [f"{gender}_%_{label}" for gender, label in percentages.columns]
# 重置索引,整理成目标输出结构
result = percentages.reset_index()

完整可运行代码

import pandas as pd

# 示例数据
data = {
    'id': [10, 10, 10, 10],
    'gender': ['male', 'female', 'male', 'male'],
    'column_1': ['a', 'b', 'c', 'b'],
    'column_2': ['b', 'c', 'c', 'a'],
    'column_3': ['a', 'b', 'a', 'a'],
    'column_n': ['b', 'c', 'a', 'b']
}
df = pd.DataFrame(data)

# 执行流程
melted_df = df.melt(id_vars=['id', 'gender'], var_name='column_name', value_name='label')
counts = melted_df.groupby(['id', 'gender', 'column_name', 'label']).size().unstack(fill_value=0)
percentages = (counts.div(counts.sum(axis=1), axis=0) * 100).round(1)
percentages.columns = [f"{g}_%_{l}" for g, l in percentages.columns]
result = percentages.reset_index()

print(result)

运行后输出结果与需求完全匹配,且可适配任意数量的column_*列。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 15:45:36