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

Pandas groupby聚合后如何链式实现avg列多条件if-else分级

Pandas链式调用实现分组统计与分级计算

原始数据

CSV文件内容如下:

key1    key2    Key3    key4    key5

Val1    A        51     'True'  25
Val1    A        50     'False' 25
Val1    A        49     'True'  25
Val1    A        48     'True'  25
Val2    A        47     'False' 25
Val2    A        46     'True'  25
Val2    A        45     'False' 25
Val2    A        44     'True'  25
Val2    A        43     'True'  25

期望输出

key1 key2 max_key5 total_key4 total_true_key4 grade
Val1  A   51       4          3                1
Val2  A   47       5          3                2

需求规则

按key1和key2分组,依次完成以下计算:

  • 统计key5的最大值
  • 统计key4列总记录行数
  • 统计key4值为'True'的总行数
  • 计算True占比百分比:avg = total_true_key4 * 100 / total_key4
  • 按占比分级:
    • avg > 70 等级为1
    • 50 < avg ≤ 70 等级为2
    • 其余情况等级为3

现有问题

当前代码中eval方法无法解析多分支if-else逻辑,且不希望拆分链式调用单独使用apply方法,原有代码如下:

grd = "1 if avg > 70 else 2 if avg > 50 else c"
pct = lambda x: (1 if x > 70 else (2 if x > 50 else 3))

json_data
    .assign(_key4=lambda df_: df_['key4'] == "'True'")
    .groupby(['key1', 'key2'])
    .agg(
        maxkey5=('key5', 'max'), 
        total_key4=('key4', 'count'), 
        total_true_key4=('_key4', 'sum')
    )
   .eval('avg = (total_true_key4 * 100) / total_key4')
   .eval('feg = grd')
  #.apply(pct(avg))

实现方案

pandas内置eval不支持嵌套多分支三元表达式,直接在链式调用中使用numpy.select或者assign配合where即可保持完整链式结构,无需拆分中间变量。

方案1:numpy.select(可读性最优)

import numpy as np

result = (
    json_data
    .assign(_key4=lambda df_: df_['key4'] == "'True'")
    .groupby(['key1', 'key2'], as_index=False)
    .agg(
        max_key5=('key5', 'max'), 
        total_key4=('key4', 'count'), 
        total_true_key4=('_key4', 'sum')
    )
    .assign(
        avg = lambda x: (x.total_true_key4 * 100) / x.total_key4,
        grade = lambda x: np.select(
            condlist=[x.avg > 70, x.avg > 50],
            choicelist=[1, 2],
            default=3
        )
    )
    .drop(columns=['avg']) # 不需要保留中间占比列可直接删除
)

方案2:Series.where嵌套(无额外依赖)

如果不想导入numpy,可使用pandas原生where方法链式判断:

result = (
    json_data
    .assign(_key4=lambda df_: df_['key4'] == "'True'")
    .groupby(['key1', 'key2'], as_index=False)
    .agg(
        max_key5=('key5', 'max'), 
        total_key4=('key4', 'count'), 
        total_true_key4=('_key4', 'sum')
    )
    .assign(
        avg = lambda x: (x.total_true_key4 * 100) / x.total_key4,
        grade = 3
    )
    .assign(grade = lambda x: x.grade.where(x.avg <= 50, 2))
    .assign(grade = lambda x: x.grade.where(x.avg <= 70, 1))
    .drop(columns=['avg'])
)

*注:如果需要匹配你给出的示例输出数值,请将聚合逻辑中max_key5=('key5', 'max')改为max_key5=('Key3', 'max'),原始数据中key5列全为25,示例输出的51、47实际是Key3列的分组最大值。

内容的提问来源于stack exchange,提问作者Md. Parvez Alam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:36:21