agg字典语法是groupby后多指标重命名的首选方法,通过{'新列名': ('原列名', 函数)}显式控制输出列名,避免默认命名混乱,兼容旧版pandas且性能更优。

用 agg 配合字典实现多指标重命名最直接
Groupby 后想对不同列应用不同聚合函数,同时给结果起新名字,agg 的字典语法是首选。它天然支持“列名 → 函数或函数列表”的映射,且能通过元组形式指定新列名。
常见错误是直接在 agg 里传入函数列表(如 ['mean', 'std']),这样会生成默认列名如 value_mean、value_std,无法自定义前缀或彻底改名。
正确做法是用 {'新列名': ('原列名', 函数)} 或 {'新列名': ('原列名', lambda x: ...)}:
df.groupby('category').agg({
'sales_mean': ('sales', 'mean'),
'sales_std': ('sales', 'std'),
'count_nonzero': ('flag', lambda x: (x != 0).sum())
})
注意:键名就是你想要的最终列名,值是二元元组 —— 第一个元素是原始列名,第二个是函数(字符串或 callable)。
避免 named_agg 在旧 Pandas 版本中失效
named_agg 是 Pandas 0.25+ 引入的更清晰写法,但如果你用的是 0.24 或更早版本,它会直接报 TypeError: aggregate() got an unexpected keyword argument 'named_agg'。
使用前务必确认版本:pandas.__version__。若需兼容老版本,统一用上面的字典 agg 写法更稳妥。
即使版本够新,也要注意 named_agg 不接受函数列表,只接受单个函数或元组;想对同一列做多个聚合,仍得拆成多个键:
# ✅ 正确
df.groupby('group').agg(
mean_val=('value', 'mean'),
max_val=('value', 'max')
)
<h1>❌ 错误:不能这样传列表</h1><p>df.groupby('group').agg(mean_max=('value', ['mean', 'max']))</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill9386" title="python学习"><img
src="https://img.php.cn/upload/skill/000/000/081/179257684888086.jpg" alt="python学习" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill9386" title="python学习" class="overflowclass">python学习</a>
<p class="overflowclass">Python 编程学习助手 skill,面向零基础用户。 当用户表达以下意图时触发: - 学习 Python 基础概念(变量、数据类型、循环、函数、类等) - 请求 Python 练习题或测验 - 请求审查或调试 Python 代码 - 请求 Python 项目实战指导(爬虫、数据分析、Web 开发等入门项目) - 泛化表述如"教我 Python""我想学编程""Python 怎么写""帮我学 Python" 此 skill </p>
</div>
<a rel="nofollow" href="/xiazai/skill9386" title="python学习" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
重命名后索引和列结构容易混乱
Groupby + agg 后,默认结果是多层列(MultiIndex),尤其当你对多列做多个聚合时。比如对 ['A', 'B'] 都用 ['mean', 'sum'],列会变成 (A, mean), (A, sum), (B, mean), (B, sum) —— 这不是你手动命名的,而是自动拼接的。
解决方法有二:
- 用字典
agg显式控制每个输出列名(推荐,见第一段) - 聚合后立刻调用
columns = columns.map('_'.join)扁平化,但会丢失语义,不便于后续引用
另一个坑是:如果 groupby 键本身是多列,结果索引也会是 MultiIndex,此时用 reset_index() 是常规操作,但要注意它会把所有层级都转为普通列 —— 若只需展平一级,得用 reset_index(level=0) 等精确控制。
性能敏感时别滥用 lambda 和自定义函数
用字符串函数名(如 'mean')比用 lambda x: x.mean() 快得多,Pandas 对前者做了底层优化。当数据量大、分组多时,这种差异会明显放大。
同理,避免在 agg 字典里反复写相同逻辑的 lambda,可先定义函数再复用:
def nonzero_ratio(x):
return (x != 0).sum() / len(x) if len(x) else 0
<p>df.groupby('cat').agg({
'ratio': ('flag', nonzero_ratio),
'total': ('amount', 'sum')
})</p>
复杂逻辑封装成函数,既提升可读性,也避免每次调用都重新解析 lambda 表达式。
重命名本身不耗资源,但命名方式决定了后续取数是否方便 —— 比如带空格或特殊字符的列名,会导致你必须用 df['my col'] 而不能用 df.my_col,这种细节在链式操作里特别容易被忽略。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










