说明

以时间索引为基础,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    30

asfreq()

说明

将时间序列转换到指定频率,插入缺失周期并填充 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')

🔗 相关链接