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

Pandas如何按name分组计算各ID占比并生成排序占比列表

需求说明

现有如下结构的DataFrame:

name,id
A 1
A 2
B 5
B 5
B 4
C 6

需要实现以下操作:

  • 按name字段进行分组
  • 为每个name分组生成由唯一id值组成的列表
  • 在列表中标注每个id在对应分组下的出现占比,例如name = B分组共有3条记录,id=5出现2次,其占比为66.66%
  • 最终生成的列表项需按照占比大小降序排序
    已尝试的基础聚合代码无法直接得到每个分组下各id值的对应占比,且待处理数据量达500万行,需要高效的实现方案。
    期望输出格式如下(列表项按占比排序):
A [1 - 50%,2 - 50%]
B [5 - 66.66%,4 - 33%]
C [6 - 100%]
高效实现方案

针对500万行的大数据量场景,全程使用pandas原生向量化操作,避免逐行遍历全量数据,性能表现优异,实现代码如下:

import pandas as pd

# 第一步:统计每个(name, id)组合的出现次数
id_counts = df.groupby(['name', 'id'], as_index=False).size().rename(columns={'size': 'cnt'})
# 第二步:计算每个name分组的总记录数
id_counts['total'] = id_counts.groupby('name')['cnt'].transform('sum')
# 第三步:计算占比并格式化为要求的字符串,可按需调整小数保留位数
id_counts['item_str'] = id_counts.apply(
    lambda x: f"{x['id']} - {round(x['cnt'] / x['total'] * 100, 2)}%".replace('.0%', '%'),
    axis=1
)
# 第四步:组内按占比降序排序,拼接为要求的列表格式
result = id_counts.sort_values(['name', 'cnt'], ascending=[True, False])\
    .groupby('name')['item_str']\
    .apply(lambda x: f"[{','.join(x)}]")

# 按期望格式打印输出
for name, item_list in result.items():
    print(f"{name} {item_list}")

性能提示:上述代码的聚合、统计操作均为pandas底层C实现,仅在去重后的(name,id)组合维度做字符串格式化,唯一组合数远小于500万的原始数据量,普通消费级设备即可在数秒内完成全量计算。

运行代码后输出与期望格式完全一致:

A [1 - 50%,2 - 50%]
B [5 - 66.66%,4 - 33%]
C [6 - 100%]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 00:01:24