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

求更简洁的Python pandas groupby分组占比实现方法

问题描述

需要对DataFrame数据按指定列进行groupby分组,计算每组中数值大于特定阈值的数据占该组总数的百分比。当前通过两次groupby生成临时DataFrame,合并后计算占比,希望找到无需创建临时DataFrame的更简洁(Pythonic)实现方式。

示例数据

import pandas as pd
df = pd.DataFrame({'n': ['a', 'b', 'c', 'a', 'c', 'a', 'a', 'c', 'a'],
                    'm': ['j', 'j', 'j', 'j', 'j', 'j', 'f', 'f', 'f'],
                    'v': [1, 1, 1, 2, 1, 2, 3, 6, 5]})

现有实现步骤

  1. 按n和m分组统计每组总数:
dfcount = df.groupby(['n', 'm'])['v'].agg('count').reset_index().rename(columns={'v': 'count'})
  1. 筛选v大于1的数据,再按n和m分组统计数量:
dfover1 = df[df['v'] > 1].groupby(['n','m']).count().reset_index().rename(columns={'v': 'over1count'})
  1. 合并两个临时DataFrame,计算占比:
dfnew = dfcount.merge(dfover1, on=['n', 'm'])
dfnew['late%'] = (100 * dfnew['over1count'] / dfnew['count']).round(1)

期望最终结果

nmcountover1countlate%
0af22100.0
1aj3266.7
2cf11100.0

简洁实现方式

以下几种方法只需一次groupby操作,无需创建临时DataFrame,代码更简洁高效:

方法一:聚合时同时计算总数和符合条件的数量

利用agg参数直接指定多个统计项,一次完成总数和达标数的计算:

result = df.groupby(['n', 'm'])['v'].agg(
    count='count',
    over1count=lambda x: (x > 1).sum()
).reset_index()
result['late%'] = (100 * result['over1count'] / result['count']).round(1)

方法二:直接计算占比(按需保留列)

如果不需要单独的count和over1count列,可直接计算占比;若需要保留总数,也能通过agg一次性完成:

# 仅保留占比列
result = df.groupby(['n', 'm'])['v'].apply(lambda x: (x > 1).mean() * 100).round(1).reset_index(name='late%')

# 同时保留总数和占比
result = df.groupby(['n', 'm'])['v'].agg(
    count='count',
    late%=lambda x: (x > 1).mean() * 100
).round(1).reset_index()

方法三:先标记达标状态再聚合

先新增一个布尔列标记数据是否符合阈值条件,再分组统计总数和达标数:

result = df.assign(over1=df['v'] > 1).groupby(['n', 'm']).agg(
    count=('v', 'count'),
    over1count=('over1', 'sum')
).reset_index()
result['late%'] = (100 * result['over1count'] / result['count']).round(1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:20:26