You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效计算带日期索引DataFrame的WoW、MoM、YoY收益率

高效计算时间序列的周/月/同比收益率

直接用pandas的向量化操作就能搞定,完全不用循环,效率高得多。以下是针对你的需求的具体实现:

先明确前提

确保你的DataFrame索引是datetime类型,如果不是先转换:df.index = pd.to_datetime(df.index);另外建议先按时间升序排序:df = df.sort_index(),避免后续计算出错。

1. 周环比(WoW)

分两种常见场景:

场景A:基于前5个交易日(和你的示例逻辑一致)

直接用shift(5)取前5个交易日的价格:

df['WoW'] = (df['CTH3 Comdty'] / df['CTH3 Comdty'].shift(5) - 1) * 100

但这种方法在遇到节假日导致一周交易日不足5天时,会取更早的日期,可能偏离“周环比”的常规含义。

场景B:基于上周同一工作日(更符合通用周环比逻辑)

用pd.DateOffset生成上周同日的日期,再通过reindex+ffill获取对应价格:

# 生成每个日期往前推1周的日期
prev_week_dates = df.index - pd.DateOffset(weeks=1)
# 匹配上周价格,无数据则向前填充
df['prev_week_price'] = df['CTH3 Comdty'].reindex(prev_week_dates, method='ffill')
# 计算收益率
df['WoW'] = (df['CTH3 Comdty'] / df['prev_week_price'] - 1) * 100

你的示例中2022-11-28的上周同日是2022-11-21,刚好有数据,计算结果和你的示例一致:≈-1.04%。

2. 月环比(MoM)

同样用DateOffset生成1个月前的日期,结合reindex+ffill处理非交易日:

# 生成1个月前的对应日期
prev_month_dates = df.index - pd.DateOffset(months=1)
# 获取对应价格,无数据则向前填充
df['prev_month_price'] = df['CTH3 Comdty'].reindex(prev_month_dates, method='ffill')
# 计算月环比收益率
df['MoM'] = (df['CTH3 Comdty'] / df['prev_month_price'] - 1) * 100

3. 同比(YoY)

逻辑和月环比完全一致,只是时间跨度改为1年:

# 生成1年前的对应日期
prev_year_dates = df.index - pd.DateOffset(years=1)
# 获取对应价格,无数据则向前填充
df['prev_year_price'] = df['CTH3 Comdty'].reindex(prev_year_dates, method='ffill')
# 计算同比收益率
df['YoY'] = (df['CTH3 Comdty'] / df['prev_year_price'] - 1) * 100

为什么这种方法更高效?

这些都是pandas内部优化的向量化操作,避免了Python循环的开销,尤其是数据量较大(比如几万条以上)时,速度会比循环+loc快几个数量级,代码也更简洁易维护。

内容的提问来源于stack exchange,提问作者Haikal Yeo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:40:48