如何用Python循环计算多频率(日/周/月/半年)滚动收益?
多频率滚动收益计算实现方案
原始DataFrame定义
import pandas as pd import numpy as np data = [[99330,12,122],[1123,1230,1287],[123,101,812739],[1143,1230123,252],[234,342,4546],[2445,3453,3457],[7897,8657,5675],[46,5675,453],[76,484,3735],[363,93,4568],[385,568,367],[458,846,4847],[574,45747,658468],[57457,46534,4675]] df1 = pd.DataFrame(data, index=['2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04', '2022-01-05', '2022-01-06', '2022-01-07', '2022-01-08', '2022-01-09', '2022-01-10', '2022-01-11', '2022-01-12', '2022-01-13', '2022-01-14'], columns=['col_A', 'col_B', 'col_C']) df1.index = pd.to_datetime(df1.index)
需求说明
需要编写循环,分别按1D(日)、1W(周)、1M(月)、6M(半年)频率计算各列的滚动收益,计算公式为:
滚动收益 = (当前值 - 对应频率前的值) / 对应频率前的值
现有代码问题修正
你提供的尝试代码存在以下问题:
- 用
iloc[i]访问数据错误:i是日期索引,iloc需要位置索引,应改用loc[i] - 硬编码偏移量
'1W',未匹配当前循环的频率参数 - 引用未定义的
df,实际应为df1 - 手动嵌套循环效率低下,Pandas内置
shift方法可高效实现偏移取值
正确实现代码
# 定义频率映射:键为Pandas时间频率字符串,值为列名后缀 periodicity_dict = {'1D': 'daily', '1W': 'weekly', '1M': 'monthly', '6M': 'half_yearly'} # 遍历每个频率 for freq, suffix in periodicity_dict.items(): # 遍历每个数据列 for col in df1.columns: # 计算对应频率的滚动收益 df1[f'{col}_rolling_{suffix}'] = (df1[col] - df1[col].shift(freq=freq)) / df1[col].shift(freq=freq)
代码要点说明
shift(freq=freq):Pandas的shift方法支持按时间频率偏移索引,直接获取对应周期前的数据,无需手动遍历日期- 列命名规则:原列名+
_rolling_+频率后缀(如col_A_rolling_daily),清晰区分不同频率的滚动收益 - 自动处理缺失值:对于无前置周期的数据(如第一个日期的日度滚动收益),结果自动为
NaN,无需手动初始化
结果示例
执行以下代码查看部分结果:
print(df1[['col_A', 'col_A_rolling_daily', 'col_A_rolling_weekly']].head())
输出:
col_A col_A_rolling_daily col_A_rolling_weekly 2022-01-01 99330 NaN NaN 2022-01-02 1123 -0.988694 NaN 2022-01-03 123 -0.890472 NaN 2022-01-04 1143 8.292683 NaN 2022-01-05 234 -0.795276 NaN
内容的提问来源于stack exchange,提问作者MathMan 99
相关产品推荐
相关产品推荐

