重采样与对齐
直觉
不同资产、不同来源的数据,往往频率不同、日期不对齐(A 股和美股交易日不同,股和债有各自停牌)。把它们塞进同一个回测前,必须先统一频率、对齐到共同的时间轴。
重采样
- 降采样(高频→低频):日→周/月,用
.resample().last()或聚合; - 升采样(低频→高频):月→日,会产生缺失,常配
.ffill()(把月度值延续到每日)。
对齐
两个 Series 相除/相加时,pandas 会按索引自动对齐——索引不一致的格子变成 NaN。多资产场景通常:
- 取所有资产的共同交易日(
df.dropna()或交集); - 或对齐后
ffill补齐。
可运行案例:多资产降采样 + 对齐收益矩阵
读取 multi_asset_daily.csv,算各资产周频收益,并对齐成一张表,确认它们已共时间轴。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('/data/multi_asset_daily.csv', parse_dates=['date']).set_index('date')
assets = ['equity', 'bond', 'commodity', 'reit']
# 日频收益(自动按索引对齐) — 4 列同时相除
daily_ret = np.log(df[assets] / df[assets].shift(1))
print("日频收益缺失(首行):"); print(daily_ret.isna().sum().to_dict())
daily_ret = daily_ret.dropna()
# 降采样到周频收益: 周内累乘的对数 = 周内对数收益求和
weekly_ret = daily_ret.resample('W').sum()
monthly_ret = daily_ret.resample('ME').sum()
print(f"\n日频行数={len(daily_ret)} 周频行数={len(weekly_ret)} 月频行数={len(monthly_ret)}")
# 确认已对齐: 每行(同一周)四资产都有值
print("周频仍有缺失的周数:", int(weekly_ret.isna().any(axis=1).sum()))
# 看看各资产周收益的相关(对齐后才能算)
print("\n周频收益相关:"); print(weekly_ret.corr().round(2))
weekly_ret.cumsum().plot(figsize=(8, 3.6))
plt.title("四类资产累计对数收益(周频, 对齐)"); plt.ylabel("累计对数收益")
plt.tight_layout(); plt.show()
小结
- 降采样用
.resample().last()(价格)或.sum()(对数收益); - pandas 运算会按索引自动对齐,不一致处变
NaN; - 多资产回测前,先统一频率并取共同时间轴。