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

如何从收益DataFrame滚动计算逆协方差矩阵及报错解决

报错本质原因
  • 运行np.linalg.inv(excess_return.rolling(750).cov().shift())报维度不匹配错误,核心是:pandas的rolling.cov()返回的是双层行索引的长表,行索引第一层为日期、第二层为10个组合名称,整体是二维扁平结构,并不是按日期拆分的三维矩阵结构。直接传入求逆函数时,numpy识别到的最后两个维度不是方阵,自然报错。
  • 运行excess_return.rolling(750).np.linalg.inv(cov()).shift()报属性错误,核心是:pandas的Rolling滚动对象没有内置numpy方法的挂载,这种写法完全不符合API调用规则,Rolling类本身不存在np属性,自然抛出属性不存在的报错。
可落地的实现代码

按照以下步骤即可实现逐交易日生成对应10×10逆协方差矩阵的需求,同时保留原代码里shift(1)的逻辑(确保计算时不使用当日收益,避免前视偏差):

  1. 计算带偏移的滚动协方差
    import numpy as np
    import pandas as pd
    
    # 750天滚动协方差计算完成后整体下移1天,每个日期的协方差仅用该日期之前的收益计算
    rolling_cov = excess_return.rolling(window=750).cov().shift(1)
    
  2. 把长格式的协方差表转换为三维矩阵结构
    # 按日期分组,将每个日期下的10行协方差数据重排为独立的10×10矩阵
    cov_mat_stack = rolling_cov.groupby(level=0).apply(
        lambda df: df.values.reshape(10, 10)
    ).values
    
  3. 批量求逆
    # numpy的linalg.inv原生支持批量处理「样本数×方阵边长×方阵边长」的三维数组
    inv_cov_mat_stack = np.linalg.inv(cov_mat_stack)
    
  4. 给逆矩阵结果绑定日期索引,方便后续调用
    rolling_cov_inv = pd.Series(
        [inv_cov_mat_stack[i] for i in range(len(inv_cov_mat_stack))],
        index=rolling_cov.index.get_level_values(0).unique()
    )
    
常见问题提示
  • 序列最开始的749个交易日因为滚动窗口长度不足750天,对应的协方差、逆协方差结果为NaN,属于正常计算结果
  • 如果运行中触发Singular matrix报错,说明对应窗口下的协方差矩阵因为组合收益完全线性相关出现奇异,可先给协方差矩阵的对角线加微小的正则项(如cov_mat_stack += np.eye(10) * 1e-8)再求逆,规避数值计算的奇异问题
  • 针对1万多条数据的量级,上述代码的运行效率完全可以满足需求,不需要额外做过度优化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 01:24:02