如何在Pandas中实现循环式跨行列滚动6个月标准差计算?
解决方案:实现循环取数的滚动6个月标准差
针对你需要计算跨年度循环取数的滚动6个月标准差需求,我们可以通过数据格式转换+自定义滚动窗口逻辑来实现,以下是具体步骤:
1. 构造示例数据(匹配你的场景)
假设你的DataFrame是宽格式,行代表年份,列代表月份:
import pandas as pd import numpy as np # 模拟你的数据:行=年份,列=月份 df = pd.DataFrame({ 'Month1': [-1.08, 0.4], 'Month2': [2.6, 1.5], 'Month3': [-0.36, -0.6], 'Month4': [-1.92, 0.8], 'Month5': [-0.84, -0.2], 'Month6': [0.01, 1.3], 'Month7': [1.2, 0.9], 'Month8': [0.5, -0.4], 'Month9': [-0.7, 0.7], 'Month10': [0.3, -0.1], 'Month11': [1.1, 1.0], 'Month12': [-0.2, 0.5] }, index=[2022, 2023])
2. 转换为长格式时间序列
宽格式不利于处理跨年度滚动,先转成以年月为索引的长格式:
# 拆解宽格式为长格式 df_long = df.unstack().reset_index() df_long.columns = ['Month', 'Year', 'Value'] # 生成日期列 df_long['Date'] = pd.to_datetime(df_long['Year'].astype(str) + '-' + df_long['Month'].str.split('_').str[1]) # 设置时间索引并排序 df_ts = df_long.set_index('Date')['Value'].sort_index()
3. 自定义循环取数的滚动标准差函数
核心逻辑:对每个年月,向前遍历6个月份;如果某个月份在当前年份不存在,就循环取上一年的对应月份数据,直到凑够6个数据点,再计算样本标准差(ddof=1,匹配你给出的示例结果):
def rolling_std_cyclic(date, ts, window=6): window_data = [] current_date = date for _ in range(window): # 如果当前日期不存在,逐年向前查找同月份数据 while current_date not in ts.index: current_date = current_date - pd.DateOffset(years=1) window_data.append(ts.loc[current_date]) # 向前移动一个月 current_date = current_date - pd.DateOffset(months=1) # 计算样本标准差(ddof=1) return np.std(window_data, ddof=1) # 应用函数到每个时间点 df_ts['Rolling_6M_Std'] = df_ts.index.map(lambda x: rolling_std_cyclic(x, df_ts))
4. 转回原宽格式(可选)
如果需要恢复成原有的年份-月份结构:
# 转换回宽格式 result = df_ts.unstack(level=1).T result.columns = [f'Month_{m}' for m in range(1, 13)]
按需调整逻辑
如果你的需求是取每个月份的最近6个年度的同月份数据(而非连续月份),只需修改函数逻辑为按月份分组取历史数据:
def rolling_std_same_month(date, ts, window=6): # 获取当前月份 month = date.month # 筛选所有同月份的数据,按年份倒序排列 same_month = ts[ts.index.month == month].sort_index(ascending=False) # 取最近window个数据 window_data = same_month.iloc[:window].values return np.std(window_data, ddof=1)
内容的提问来源于stack exchange,提问作者dgoodie
相关产品推荐
相关产品推荐

