如何用Pandas的groupby与rolling计算不同时段DataFrame列的最值
用Rolling + Groupby实现DataFrame分时段最值计算
需求说明
针对DataFrame的某一列,计算第1-30天、30-60天、60-90天三个时段的最大值和最小值,要求结合rolling和groupby实现。
步骤实现
1. 构造示例数据
先创建一个包含90天时间序列的示例DataFrame,模拟真实场景:
import pandas as pd import numpy as np # 生成连续90天的日期序列 dates = pd.date_range(start='2023-01-01', periods=90) df = pd.DataFrame({'date': dates, 'value': np.random.randn(90)*10 + 50})
2. 预处理:日期索引与分组标签
将日期设为索引,并生成30天周期的分组标签,把时间序列划分为3个目标时段:
# 将日期列设为索引,方便时间相关操作 df = df.set_index('date') # 计算每个日期与起始日的天数差,按30天为周期生成分组标签 # 标签0=1-30天,1=30-60天,2=60-90天 df['window_group'] = (df.index - df.index[0]).days // 30
3. 结合Rolling与Groupby计算最值
对每个30天分组,用rolling窗口覆盖整个组的数据集,再计算最值:
# 按分组标签聚合,对每个组的value列应用rolling窗口(窗口大小为组内数据长度) # 聚合max和min后,去重保留每个组的最终结果 result = df.groupby('window_group')['value'].rolling( window=lambda x: len(x) # 窗口大小等于当前组的行数(即30天的数据量) ).agg(['max', 'min']).reset_index() # 清理结果:每个分组只保留最后一行(即整个时段的最值) result = result.drop_duplicates('window_group', keep='last').set_index('window_group')
4. 最终结果示例
输出的result格式如下,对应三个时段的最值:
max min window_group 0 68.2345 32.1098 1 65.7890 35.4321 2 70.1234 30.9876
关键说明
- 为什么不用
iloc/loc?手动切片(如df.iloc[0:30])仅适用于连续无缺失的日期序列,若数据存在日期缺失或时段长度不固定,这种方法会失效。而rolling+groupby的方式可以自适应处理时间分组,鲁棒性更强。 rolling(window=lambda x: len(x))的作用:让每个分组的滚动窗口刚好覆盖该组的所有数据,确保计算的是整个时段的最值,而非滑动窗口的局部值。- 若数据存在缺失日期,可调整
rolling的min_periods参数(如min_periods=20),允许窗口内最少包含20个数据点再计算最值。
内容的提问来源于stack exchange,提问作者Yogesh Kamboj
相关产品推荐
相关产品推荐

