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

如何在Python的groupby聚合中添加聚合间的数学运算?

在Pandas Groupby聚合中直接实现跨列数学运算

嘿,我明白你想在groupby的聚合操作里一步完成统计和比率计算的需求!你之前的写法没法生效是因为agg()的字典参数里不能直接对未完成的聚合结果做运算——毕竟聚合还没执行,那些类似('repair':"count")的写法既不合法,也没法拿到实际的数值。

下面给你两种实用的方法,能直接在聚合流程里完成你要的计算:

方法1:使用命名聚合+Lambda函数

这种方法简洁直观,利用Pandas的命名聚合特性,同时完成计数和比率计算:

import pandas as pd

# 模拟你的原始数据(补充重复行让groupby有实际统计意义)
df = pd.DataFrame({
    'yr': [2016]*37,  # 对应你给出的2016年id计数37
    'id': range(37),
    'repair': [1]*27 + [0]*10  # 对应2016年repair计数27
})
df = pd.concat([df, pd.DataFrame({
    'yr': [2017]*53,  # 2017年id计数53
    'id': range(53),
    'repair': [1]*28 + [0]*25  # 2017年repair计数28
})])

# 一步完成聚合和比率计算
agg_result = df.groupby('yr').agg(
    id_count=('id', 'count'),  # 统计id的数量
    repair_count=('repair', 'count'),  # 统计repair的数量
    repair_rate=lambda group: round((group['repair'].sum() / group['id'].count()) * 100, 2)  # 计算比率并转百分比,保留两位小数
)

print(agg_result)

运行后会得到你想要的结果:

yrid_countrepair_countrepair_rate
2016373772.97
2017535352.83

方法2:自定义聚合函数(适合复杂计算)

如果之后需要加入更复杂的逻辑(比如除以0的异常处理、多步转换),自定义函数会更灵活:

def calculate_group_stats(group):
    # 先计算基础统计值
    id_total = group['id'].count()
    repair_total = group['repair'].sum()  # 如果repair是标记列用sum,是计数用count
    # 处理除以0的情况
    if id_total == 0:
        repair_ratio = 0.0
    else:
        repair_ratio = (repair_total / id_total) * 100
    # 返回包含所有结果的Series
    return pd.Series({
        'id_count': id_total,
        'repair_count': repair_total,
        'repair_rate': round(repair_ratio, 2)
    })

# 应用自定义函数到分组
agg_result = df.groupby('yr').apply(calculate_group_stats)

这种方法的优势是可以在函数里封装所有业务逻辑,扩展性更强。

为什么你之前的写法不生效?

你尝试的agg({ 'id':"count", 'repair':"count", ('repair':"count")/('id':"count") })存在两个核心问题:

  1. 字典的键只能是最终的列名,不能直接写运算表达式;
  2. ('repair':"count")不是合法的Python语法,而且此时聚合还没执行,根本拿不到count的结果,自然无法做除法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:58:48