如何在 Pandas GroupBy 中实现跨多列的自定义聚合计算

秋敏同学_6456

秋敏同学_6456

2026-10-01

311人浏览

原创

如何在 Pandas GroupBy 中实现跨多列的自定义聚合计算

Pandas 的 groupby.agg() 默认不支持直接在聚合函数中同时访问多个列,但可通过预计算新列或改用 groupby.apply() 实现多列协同计算,本文详解两种可靠方案及性能权衡。

pandas 的 `groupby.agg()` 默认不支持直接在聚合函数中同时访问多个列,但可通过预计算新列或改用 `groupby.apply()` 实现多列协同计算,本文详解两种可靠方案及性能权衡。

在 Pandas 中进行分组聚合时,一个常见需求是:基于同一分组内多个数值列的组合运算(如 value1 * value2 的均值)生成新统计量。然而,DataFrameGroupBy.agg() 的标准用法(包括字典映射、命名元组或关键字参数形式)仅允许每个聚合函数作用于单列——即函数接收的是 Series,而非整个子 DataFrame。因此,如下写法会报错或行为异常:

# ❌ 错误示例:agg 不支持 lambda 中跨列访问
df.groupby(["Sample", "Year"]).agg(agg1=lambda group: (group["value1"] * group["value2"]).mean())

✅ 方案一:预计算辅助列 + agg()(推荐)

最高效、最符合 pandas 惯例的方式是先构造中间列,再分组聚合。利用 eval() 或普通赋值创建临时列,随后在 agg() 中引用该列:

import pandas as pd

df = pd.DataFrame({
    "value1": range(8), 
    "value2": range(7, -1, -1), 
    "Sample": [1, 2] * 4, 
    "Year": list(range(2023, 2027)) * 2
})

result = (df.eval('prod = value1 * value2')
          .groupby(['Sample', 'Year'])
          .agg(agg1=('prod', 'mean')))
print(result)

输出:

             agg1
Sample Year      
1      2023   6.0
       2025   8.0
2      2024   8.0
       2026   6.0

✅ 优势:向量化计算、内存友好、可链式调用、兼容 .agg() 的所有高级功能(如多函数、多列映射)。
⚠️ 注意:若需保留原始 DataFrame 结构,可在链式操作末尾加 .drop(columns='prod')。

✅ 方案二:使用 groupby.apply()(灵活但慎用)

当逻辑极其复杂(如涉及条件分支、外部状态或非标量返回)时,apply() 允许函数接收整个分组 DataFrame,从而自由访问任意列:

result_apply = (df.groupby(['Sample', 'Year'])
                .apply(lambda x: x['value1'].mul(x['value2']).mean()))
# 返回 Series,索引为 MultiIndex
print(result_apply)

输出:

Sample  Year
1       2023    6.0
        2025    8.0
2       2024    8.0
        2026    6.0
dtype: float64

⚠️ 注意事项:

  • apply() 是逐组 Python 循环,性能显著低于向量化操作(尤其大数据集);
  • 默认返回 Series,若需 DataFrame 输出,需显式构造(如 lambda x: pd.Series({'agg1': ...}));
  • 避免在 apply 中重复调用 .copy() 或复杂 I/O,否则进一步拖慢速度。

总结建议

场景 推荐方法 理由
多列简单算术/统计(如乘积均值、差值标准差) eval() + agg() 高效、清晰、可读性强、易于调试
需要分组内行间逻辑、动态列选择或非标量输出 apply() 灵活性高,但务必评估性能影响
需同时对多列做不同聚合(如 value1.sum() 和 value2.mean()) 直接 agg({'value1': 'sum', 'value2': 'mean'}) 原生支持,无需跨列

始终优先尝试向量化预计算;仅当 agg() 无法满足逻辑表达时,再启用 apply() 并辅以性能测试(如 %%timeit)。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

2025.12.04

300

15

Python 数据清洗与预处理实战
Python 数据清洗与预处理实战

本专题系统讲解 Python 在数据清洗与预处理中的核心技术,包括使用 Pandas 进行缺失值处理、异常值检测、数据格式化、特征工程与数据转换,结合 NumPy 高效处理大规模数据。通过实战案例,帮助学习者掌握 如何处理混乱、不完整数据,为后续数据分析与机器学习模型训练打下坚实基础。

2026.01.31

212

21

Python数据分析与Pandas高级实战
Python数据分析与Pandas高级实战

本专题围绕 Python 数据分析展开,系统讲解 Pandas 的高级用法,包括数据清洗、透视表、时间序列分析以及多表合并与分组操作。通过实战案例,帮助开发者掌握高效处理与分析数据的方法,提高数据处理效率与分析能力。

2026.04.13

371

25

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

2026.09.30

0

10

LLVM RISC-V参数配置教程
LLVM RISC-V参数配置教程

本专题介绍LLVM对RISC-V基础ISA和扩展的支持方式,涵盖RV32、RV64、标准扩展、实验性扩展、厂商扩展、-menable-experimental-extensions和版本差异。

2026.09.30

0

14

LLVM IR中间表示入门指南
LLVM IR中间表示入门指南

本专题整理LLVM IR的核心概念,包括中间表示作用、模块结构、函数、基本块、SSA形式、类型系统和常见语法,帮助新手理解LLVM编译流程中的关键层。

2026.09.30

0

12

PDF转图片方法
PDF转图片方法

需要把 PDF 页面用于上传、预览、分享或图片归档时,PDF 转图片方法专题整理 JPG/PNG 格式选择、逐页导出、清晰度设置、批量下载和结果检查等流程,帮助用户稳定完成 PDF 图片化处理。

2026.09.30

0

26

PixTV AI视频生成与无限画布创作
PixTV AI视频生成与无限画布创作

PixTV专题整理AI视频与视觉内容创作相关功能使用教程,涵盖AI生图、视频生成、无限画布、多模型创作、素材管理、声音音乐及视频剪辑等功能,帮助用户快速掌握PixTV从创意到成片的完整制作方法。

2026.09.29

0

15

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

2026.09.23

220

15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.4万人学习