如何在循环中创建Pandas多级索引DataFrame并计算相关系数百分位排名
解决滚动窗口相关系数的百分位排名问题
嘿,我来帮你搞定这个滚动26周相关系数的百分位排名需求!你的思路完全正确,用多级索引来存储所有窗口的相关系数是最清晰的方案,接下来我一步步给你拆解实现过程:
第一步:准备测试数据
先把你给的测试代码优化得更简洁些,确保差分数据处理正确:
import pandas as pd import numpy as np # 生成周度时间序列测试数据 daterange = pd.date_range('20160701', periods=100, freq='1w') np.random.seed(120) df_corr = pd.DataFrame(np.random.rand(100,5), index=daterange, columns=list('abcde')) # 计算差分并处理缺失值和0值 df_corr_chg = df_corr.diff().dropna() # 直接删除首行缺失值,替代手动切片 df_corr_chg = df_corr_chg.replace(0, 0.01)
第二步:生成所有滚动窗口的相关系数(多级索引存储)
我们需要遍历每个26周的滚动窗口,计算每个窗口的相关系数矩阵,然后把所有结果整理到一个以窗口结束日期、变量对为多级索引的DataFrame中:
window_size = 26 corr_results = [] for end_idx in range(window_size, len(df_corr_chg) + 1): # 提取当前滚动窗口的数据 window_data = df_corr_chg.iloc[end_idx - window_size : end_idx] # 计算窗口内的相关系数矩阵 corr_mat = window_data.corr() # 给当前矩阵添加窗口结束日期标识 corr_mat['window_end'] = window_data.index[-1] # 把宽格式的相关系数矩阵转成长格式,方便合并所有窗口结果 corr_long = corr_mat.set_index('window_end').stack().reset_index() corr_long.columns = ['window_end', 'var1', 'var2', 'corr_value'] corr_results.append(corr_long) # 合并所有窗口结果,设置多级索引:(window_end, var1, var2) corr_df = pd.concat(corr_results).set_index(['window_end', 'var1', 'var2'])
第三步:计算最新窗口相关系数的百分位排名
现在我们有了所有历史窗口的相关系数,接下来针对每个变量对,计算最新窗口的相关系数在所有历史值中的百分位排名:
# 获取最新窗口的结束日期 latest_window_end = corr_df.index.get_level_values('window_end').max() # 1. 提取最新窗口的相关系数值 latest_corr_values = corr_df.xs(latest_window_end, level='window_end').rename(columns={'corr_value': 'current_corr'}) # 2. 按变量对分组,计算每个相关系数值的百分位排名(pct=True返回0-1之间的百分位) rank_data = corr_df.groupby(['var1', 'var2'])['corr_value'].rank(pct=True) # 提取最新窗口的排名结果 latest_ranks = rank_data.xs(latest_window_end, level='window_end').rename('percentile_rank') # 3. 合并相关系数和排名,生成最终展示表格 final_result = pd.concat([latest_corr_values, latest_ranks], axis=1) # 调整索引顺序,让展示更直观(按var2、var1排序) final_result = final_result.swaplevel().sort_index()
示例输出
运行完上面的代码后,final_result会是一个多级索引的表格,类似你期望的格式,示例片段如下:
| var2 | var1 | current_corr | percentile_rank |
|---|---|---|---|
| a | a | 1.0 | 1.0 |
| a | b | -0.101713 | 0.22 |
| a | c | 0.031109 | 0.68 |
| b | a | -0.101713 | 0.22 |
| b | b | 1.0 | 1.0 |
| b | c | -0.031109 | 0.35 |
关键逻辑说明
- 用多级索引
(window_end, var1, var2)可以精准定位每个窗口下每对变量的相关系数,方便后续分组计算排名 groupby(['var1', 'var2'])确保我们只在同一变量对的历史值中计算排名,不会混淆不同变量对的数据rank(pct=True)直接返回百分位排名(0表示最低,1表示最高),完美匹配你的需求
内容的提问来源于stack exchange,提问作者djtmj
相关产品推荐
相关产品推荐

