如何在Pandas时间序列DataFrame中计算并维护滚动最大值的最后两个不同值
Pandas实现126天滚动最大值及衍生列计算
需求说明
针对含每日价格数据的Pandas DataFrame,需完成以下操作:
- 计算**126天窗口(6个月周期)**的滚动最大值列
rolling_max - 新增两列:
last_distinct_rolling_max:存储当前滚动最大值之前的上一个不同滚动最大值,新最大值未出现时保持该值second_last_distinct_rolling_max:存储滚动最大值序列中的倒数第二个不同值
示例数据与预期输出
| 日期时间(DateTime) | 价格(Price) | 滚动最大值(rolling_max) | last_distinct_rolling_max | second_last_distinct_rolling_max |
|---|---|---|---|---|
| 2007-12-31 | 1468.36 | 1468.36 | NaN | NaN |
| 2008-01-02 | 1477.16 | 1477.16 | 1468.36 | NaN |
| 2008-01-03 | 1450 | 1477.16 | 1468.36 | NaN |
| 2008-01-04 | 1490 | 1490 | 1477.16 | 1468.36 |
代码实现
import pandas as pd # 假设你的DataFrame名为df,先将DateTime列设为索引 df = df.set_index('日期时间(DateTime)') # 1. 计算126天滚动最大值,min_periods=1确保数据开头不足窗口时也能计算 df['rolling_max'] = df['价格(Price)'].rolling(window=126, min_periods=1).max() # 2. 提取滚动最大值发生变化的行,得到唯一最大值序列 distinct_max = df['rolling_max'].loc[df['rolling_max'] != df['rolling_max'].shift(1)] # 3. 为每个新最大值关联上一个、倒数第二个最大值 distinct_max = distinct_max.reset_index() distinct_max['last_distinct'] = distinct_max['rolling_max'].shift(1) distinct_max['second_last_distinct'] = distinct_max['rolling_max'].shift(2) # 4. 合并回原DataFrame,用前向填充补全所有行的衍生值 df = df.merge(distinct_max[['日期时间(DateTime)', 'last_distinct', 'second_last_distinct']], left_index=True, right_on='日期时间(DateTime)', how='left') df['last_distinct_rolling_max'] = df['last_distinct'].ffill() df['second_last_distinct_rolling_max'] = df['second_last_distinct'].ffill() # 清理临时列 df = df.drop(columns=['日期时间(DateTime)', 'last_distinct', 'second_last_distinct'])
关键逻辑说明
- 用
shift()和布尔索引筛选滚动最大值的变化点,避免重复值干扰衍生列计算 ffill()前向填充确保非变化点的行继承最近一次最大值更新时的衍生值,符合需求中“新最大值出现前保持上一个值”的要求
内容的提问来源于stack exchange,提问作者Aliz
相关产品推荐
相关产品推荐

