说明
以时间索引为基础,pandas 提供了移位、频率转换、重采样、滑动窗口、时间区间切片与对齐等时间序列专属操作。
shift()
说明
将数据沿时间轴平移指定周期,常用于计算环比、差分特征。
import pandas as pd
s = pd.Series([10, 20, 30], index=pd.date_range('2026-01-01', periods=3, freq='D'))
print(s.shift(1))
# 2026-01-01 NaN
# 2026-01-02 10.0
# 2026-01-03 20.0
# 负数向前平移
print(s.shift(-1))
# 2026-01-01 20.0
# 2026-01-02 30.0
# 2026-01-03 NaN
# 按频率平移(填补缺失周期)
print(s.shift(1, freq='D'))
# 2026-01-02 10
# 2026-01-03 20
# 2026-01-04 30asfreq()
说明
将时间序列转换到指定频率,插入缺失周期并填充
NaN(或按method填充)。
s = pd.Series([1, 2, 3], index=pd.date_range('2026-01-01', periods=3, freq='D'))
print(s.asfreq('h')) # 转为小时频率,未覆盖时间点出现 NaN
print(s.asfreq('h', method='ffill')) # 向前填充
print(s.asfreq('W-MON')) # 转为每周一resample()
说明
将时间序列重采样到更低或更高频率,是时间序列聚合的核心方法。
# 降采样:日数据聚合成月数据
daily = pd.Series(
range(1, 32),
index=pd.date_range('2026-01-01', periods=31, freq='D'),
)
monthly = daily.resample('ME').sum() # 或 'M'
print(monthly)
# 2026-01-31 496
# 重采样 + 多种聚合
print(daily.resample('W').agg(['sum', 'mean', 'max']))
# 升采样:插值
hourly = daily.resample('h').ffill()
# 使用 origin 参数对齐分桶
print(daily.resample('7D', origin='2026-01-01').sum())rolling() / expanding() / ewm()
说明
三种滑动窗口计算:
rolling():固定窗口滑动计算。expanding():扩展窗口(从起点到当前点)。ewm():指数加权移动计算。
s = pd.Series(range(1, 11), index=pd.date_range('2026-01-01', periods=10, freq='D'))
# 固定 3 日窗口
print(s.rolling(3).mean())
# 2026-01-01 NaN
# 2026-01-02 NaN
# 2026-01-03 2.0
# ...
# 基于时间的窗口(3 天内)
print(s.rolling('3D').sum())
# 扩展窗口
print(s.expanding().sum())
# 指数加权
print(s.ewm(span=3).mean())详细说明
滚动 / 扩展 / 指数加权窗口的完整参数与方法见 十七、窗口计算。
between_time()
说明
筛选一天中特定时间区间内的数据(要求索引为 DatetimeIndex 且按时间排序)。
idx = pd.date_range('2026-08-19 00:00', periods=24, freq='h')
s = pd.Series(range(24), index=idx)
# 选取 09:00 至 17:00 之间的数据
print(s.between_time('09:00', '17:00'))
# 2026-08-19 09:00 9
# 2026-08-19 10:00 10
# ...
# 2026-08-19 17:00 17
# include_start / include_end 控制边界
print(s.between_time('09:00', '17:00', include_start=False, include_end=False))at_time()
说明
精确选取一天中某一时刻的数据。
idx = pd.date_range('2026-08-19 00:00', periods=48, freq='30min')
s = pd.Series(range(48), index=idx)
print(s.at_time('09:00'))
# 2026-08-19 09:00:00 18
# 多天数据时返回所有日期中该时刻的值
idx2 = pd.date_range('2026-08-19 00:00', '2026-08-21 23:59', freq='h')
s2 = pd.Series(range(len(idx2)), index=idx2)
print(s2.at_time('12:00'))first() / last()
说明
基于相对时间长度(如
'5D'、'1M')选择时间序列的开头/末尾片段。
s = pd.Series(range(30), index=pd.date_range('2026-01-01', periods=30, freq='D'))
print(s.first('5D')) # 前 5 天
print(s.last('1W')) # 最后 1 周
print(s.first('2ME')) # 前 2 个月时间对齐
说明
pandas 在进行时间索引运算时,会自动按时间戳对齐,缺失部分得到
NaN。
s1 = pd.Series([1, 2, 3], index=pd.date_range('2026-01-01', periods=3, freq='D'))
s2 = pd.Series([10, 20, 30], index=pd.date_range('2026-01-02', periods=3, freq='D'))
print(s1 + s2)
# 2026-01-01 NaN
# 2026-01-02 12.0
# 2026-01-03 23.0
# 2026-01-04 NaN
# 使用 reindex / align 实现手动对齐
s1_aligned, s2_aligned = s1.align(s2, join='inner')