如何高效计算Pandas中各personID的points列滑动最小值?
按分组计算累计最小值的高效实现方法
针对你的需求,最直接高效的方式是利用Pandas的分组(groupby)结合累计最小值函数(cummin),或者扩展窗口函数(expanding().min())来实现,完全不需要依赖shift()。
核心解法:用groupby + cummin()
cummin()会自动对每个分组内的序列,逐行计算从第一行到当前行的最小值,完美匹配你要的"每个personID对应行及之前所有points值的最小值"的需求,代码简洁且性能优异。
示例代码如下:
import pandas as pd # 构造示例数据 df = pd.DataFrame({ 'personID': [1,1,1,2,2,3,3,3,3], 'points': [10, 5, 8, 15, 12, 7, 3, 9, 2] }) # 新增localMin列 df['localMin'] = df.groupby('personID')['points'].transform('cummin')
执行后得到的结果:
| personID | points | localMin |
|---|---|---|
| 1 | 10 | 10 |
| 1 | 5 | 5 |
| 1 | 8 | 5 |
| 2 | 15 | 15 |
| 2 | 12 | 12 |
| 3 | 7 | 7 |
| 3 | 3 | 3 |
| 3 | 9 | 3 |
| 3 | 2 | 2 |
备选方案:groupby + expanding().min()
如果你需要更明确的窗口逻辑,也可以用expanding()窗口结合min(),效果和cummin()完全一致:
df['localMin'] = df.groupby('personID')['points'].expanding().min().reset_index(level=0, drop=True)
为什么shift()不适用
shift()只是单纯地将序列行向上/向下移动,无法维护每个分组的累计最小值状态,自然无法实现"从分组开头到当前行的最小值"这类需要持续追踪状态的计算。
性能说明
以上两种方法都是Pandas内部优化过的矢量化操作,避免了手动循环分组的低效问题,即使处理百万级别的大型数据集,也能保持良好的运行效率。
内容的提问来源于stack exchange,提问作者Joseph K.
相关产品推荐
相关产品推荐

