如何通过apply将分组计算值回填至原Pandas DataFrame?
高效实现Pandas分组后新增列的方法
嘿,这个问题我太熟了——很多刚上手Pandas做分组计算的朋友都会先想到手动循环,但其实Pandas原生就有更简洁高效的方案,完全不用折腾子DataFrame再回填!
最直接的方案:用transform方法
transform是专门干这个的:它会对每个分组执行计算,然后把结果广播回原DataFrame的每一行,完美匹配你要的效果。
比如你举的平均值例子,一行代码就能搞定:
import pandas as pd # 你的原始数据 df = pd.DataFrame({'a': [1,1,2,2], 'b': [2,3,4,5]}) # 新增c列,填充每组a对应的b列平均值 df['c'] = df.groupby('a')['b'].transform('mean')
运行后直接得到你想要的结果:
| a | b | c |
|---|---|---|
| 1 | 2 | 2.5 |
| 1 | 3 | 2.5 |
| 2 | 4 | 4.5 |
| 2 | 5 | 4.5 |
如果是你自己的MyFunction,只要这个函数接收一个Series(每组的b列数据)并返回一个标量,直接传给transform就行:
def MyFunction(series): # 这里写你的自定义逻辑,比如计算极差 return series.max() - series.min() df['c'] = df.groupby('a')['b'].transform(MyFunction)
备选方案:groupby计算后用map映射
如果需要先把分组计算的结果存下来复用,这种方法也很直观:
# 先计算每组的平均值,得到一个以a为索引的Series group_stats = df.groupby('a')['b'].mean() # 用map把a列的值对应到group_stats里的结果 df['c'] = df['a'].map(group_stats)
效果和transform完全一样,适合需要多次使用分组结果的场景。
为什么不推荐你的循环方法?
- 效率低:Pandas的核心是矢量化操作,手动循环会绕过这些优化,数据量大的时候速度差会非常明显。
- 代码冗余:还要手动筛选子DataFrame,最后还要考虑怎么把结果回填到原DataFrame,容易出错(比如索引不匹配的问题)。
内容的提问来源于stack exchange,提问作者Lostsoul




