如何获取pandas groupby对象的expanding最大值并解决索引报错
错误原因
这个IndexError: index 97 is out of bounds for axis 0 with size 97是pandas中groupby和expanding联用时的索引对齐bug导致的:
- 分组后直接调用
expanding()返回的结果带有双层索引结构:第一层是pd.Grouper生成的15分钟分组时间键,第二层才是原数据的DatetimeIndex - 直接将双层索引的计算结果赋值给原单层索引的DataFrame列时,pandas的索引匹配逻辑出错,就会触发数组越界报错。
顺带提一句,你贴的样例代码里date_range生成的时间范围是2015-01-01到2015-01-02,但打印的df结果到了2015-01-07,属于笔误,不影响问题复现。
解决方案
有两种稳定可用的实现方式,计算逻辑完全符合「每个15分钟区间内逐行计算从区间起点到当前行的最大值」的需求:
方式一:直接使用分组累计最大值(性能最好,写法最简洁)
分组内的expanding最大值本质就是分组累计最大值,用内置的cummax方法可以直接避开索引对齐问题:import pandas as pd import numpy as np np.random.seed(0) indexcol = pd.date_range('01-01-2015 00:00:00','01-02-2015 00:00:00',freq='1min',tz='Europe/Amsterdam') df = pd.DataFrame({'value':np.random.random(len(indexcol))},index=indexcol) df = (df - 0.5).cumsum() # 计算15分钟分组内的expanding最大值 df['15min_expanding_max'] = df.groupby(pd.Grouper(freq='15min'))['value'].cummax()方式二:保留expanding接口写法(适配复杂窗口计算场景)
如果你后续需要替换为其他expanding算子(比如expanding均值、标准差、自定义聚合等),可以在计算后删除多余的分组索引层,保证结果和原DataFrame索引完全对齐:df['15min_expanding_max'] = df.groupby(pd.Grouper(freq='15min'))['value'].expanding().max().droplevel(0)
两种写法的计算结果完全一致:每进入一个新的15分钟时间窗口,累计最大值就会重置,从窗口内的第一个值开始重新逐行计算累计最大值,且上述写法在pandas 1.0+所有版本均可稳定运行,不存在版本兼容问题。
内容的提问来源于stack exchange,提问作者jcnc
相关产品推荐
相关产品推荐

