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

Pandas 计算金融实体季度数据多周期年化收益率的效率优化问题

核心优化思路

原代码逐行遍历+全表筛选的实现时间复杂度为O(n²),大样本下性能极差。我们可以使用分组滚动窗口+向量化运算将时间复杂度降到O(n),性能提升可达上千倍。
利用对数性质ln(a*b) = ln(a) + ln(b),将滚动乘积转换为更高效的滚动求和,同时避免浮点精度误差。


实现代码

1. 基础版本(数据无缺失季度时使用)

import pandas as pd
import numpy as np

# 第一步:数据预处理,确保日期格式正确、按实体+时序排序
df['Date'] = pd.to_datetime(df['Date'])
df = df.sort_values(by=['Entity', 'Date']).reset_index(drop=True)

# 第二步:配置所有需要计算的周期,新增周期只需修改此处
# 格式:{输出列名: (窗口大小<季度数>, 年化指数)}
period_config = {
    'R_1yr': (4, 1/1),
    'R_3yr': (12, 1/3),
    'R_5yr': (20, 1/5),
    'R_7yr': (28, 1/7),
    'R_10yr': (40, 1/10),
    'R_15yr': (60, 1/15),
    'R_20yr': (80, 1/20)
}

# 第三步:核心计算逻辑
# 先计算对数收益率,方便滚动求和替代乘积
df['log_return'] = np.log(1 + df['r_qrt'])
grouped = df.groupby('Entity')['log_return']

for col_name, (window_size, ann_factor) in period_config.items():
    # 滚动求和,不足窗口大小的自动返回NaN,完全匹配原逻辑的计数判断
    rolling_sum = grouped.rolling(window=window_size, min_periods=window_size).sum().reset_index(level=0, drop=True)
    # 转换为年化收益率
    df[col_name] = np.exp(rolling_sum) ** ann_factor - 1

# 删掉辅助列得到最终结果
df = df.drop(columns=['log_return'])

2. 兼容缺失季度版本

如果数据存在部分季度缺失的情况,需要先补全每个实体的季度时间序列,避免滚动窗口计数错误:

# 补全缺失季度的代码,放在预处理步骤之后、核心计算之前
df = df.set_index('Date')
df = df.groupby('Entity').apply(
    lambda x: x.asfreq('Q', fill_value=np.nan)
).drop(columns=['Entity']).reset_index()

性能说明

百万行级别的长时序多实体数据,该实现耗时通常在10秒以内,远低于原实现的2小时以上耗时,计算结果和原逐行逻辑完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 19:24:11