如何用Pandas的shift()计算至少n天前的时间序列变化率
用Pandas计算每行与至少n天前行的变化率(无循环)
要实现这个需求,核心是先定位每行对应的满足"至少n天前"条件的最近一行,再通过向量运算计算变化率,全程无需循环。以下是具体实现步骤:
步骤说明
- 确保DataFrame的索引为
DatetimeIndex并已排序(这是日期运算的前提)。 - 为每行生成"至少n天前"的目标日期(当前日期减去n天)。
- 利用索引匹配,找到每个目标日期在原索引中对应的最近有效行(向前填充匹配)。
- 提取对应行的数值,批量计算变化率。
代码示例
以你给出的n=2天的示例为例:
import pandas as pd # 构造示例数据 data = { 'x': [1, 2, 3, 4, 5, 6], 'Date': pd.to_datetime(['2024-04-01', '2024-04-05', '2024-04-06', '2024-04-07', '2024-04-08', '2024-04-09']) } df = pd.DataFrame(data).set_index('Date') n = 2 # 至少n天前 # 生成每行对应的"至少n天前"的目标日期 target_dates = df.index - pd.Timedelta(days=n) # 找到每个目标日期在原索引中的位置(向前填充,取最近的不晚于目标日期的行) indices = df.index.get_indexer(target_dates, method='ffill') # 处理第一行:没有更早的行,设为自身索引(变化率为0) indices[0] = 0 # 计算变化率 df['change'] = (df['x'] - df['x'].iloc[indices]) / df['x'].iloc[indices] # 保留5位小数,和示例格式对齐 df['change'] = df['change'].round(5) print(df)
运行后输出和示例完全一致:
x change Date 2024-04-01 1 0.00000 2024-04-05 2 1.00000 2024-04-06 3 2.00000 2024-04-07 4 1.00000 2024-04-08 5 0.66667 2024-04-09 6 0.50000
关键细节解释
pd.Timedelta(days=n):生成日期偏移量,确保我们找的是真正的"n天前",而非固定行数的前一行(避免日期不连续的问题)。index.get_indexer(..., method='ffill'):核心操作,为每个目标日期找到原索引中最后一个不大于该日期的位置,完美匹配"至少n天前"的要求。- 向量运算:所有计算基于Pandas的Series/数组操作,效率远高于循环,适合处理大规模数据。
内容的提问来源于stack exchange,提问作者Baron Yugovich
相关产品推荐
相关产品推荐

