首页 > 解决方案 > 如何从相关矩阵和波动率向量创建协方差矩阵?

问题描述

我在数据框中有这个相关矩阵df_corr

ticker     CNP         F        GE      TSLA       WMT                                                  
CNP     1.000000  0.302712  0.408604  0.205812  0.289421
F       0.302712  1.000000  0.510077  0.302415  0.280815
GE      0.408604  0.510077  1.000000  0.288827  0.326106
TSLA    0.205812  0.302415  0.288827  1.000000  0.166978
WMT     0.289421  0.280815  0.326106  0.166978  1.000000

我在数据框中有这个波动率向量df_vol

CNP       0.012789
F         0.014525
GE        0.011579
TSLA      0.026573
WMT       0.011369

我想要协方差矩阵。我不能在我的真实示例中使用 numpy cov,因为波动性和相关性不是来自同一张表。

以下是预期结果:

ticker     CNP        F        GE       TSLA       WMT    
CNP     0.000164  0.000056  0.000061  0.000070  0.000042
F       0.000056  0.000211  0.000086  0.000117  0.000046
GE      0.000061  0.000086  0.000134  0.000089  0.000043
TSLA    0.000070  0.000117  0.000089  0.000707  0.000051
WMT     0.000042  0.000046  0.000043  0.000051  0.000129

标签: pythonpython-3.xpandasnumpy

解决方案


IIUC,考虑到您有以下设置

Setup

z = io.StringIO("""
ticker     CNP         F        GE      TSLA       WMT                                                  
CNP     1.000000  0.302712  0.408604  0.205812  0.289421
F       0.302712  1.000000  0.510077  0.302415  0.280815
GE      0.408604  0.510077  1.000000  0.288827  0.326106
TSLA    0.205812  0.302415  0.288827  1.000000  0.166978
WMT     0.289421  0.280815  0.326106  0.166978  1.000000""")

df = pd.read_table(z, delim_whitespace=True)

z2= io.StringIO("""
ticker vol
CNP       0.012789
F         0.014525
GE        0.011579
TSLA      0.026573
WMT       0.011369""")

df2 = pd.read_table(z2, delim_whitespace=True)

您可以获取stack这些值,并使用它map来检索 vol 值。然后乘以

所以首先stack

df = df.set_index('ticker').stack().reset_index()
df.columns = ['ticker', 'other', 'corr']

这样你得到

   ticker other      corr
0     CNP   CNP  1.000000
1     CNP     F  0.302712
2     CNP    GE  0.408604
3     CNP  TSLA  0.205812
4     CNP   WMT  0.289421
5       F   CNP  0.302712
6       F     F  1.000000
7       F    GE  0.510077
8       F  TSLA  0.302415
9       F   WMT  0.280815

然后过滤掉相等的值(它们无关紧要)

df = df[df.ticker != df.other]

map

df2 = df2.set_index('ticker')
df['cov'] = df.ticker.map(df2.vol) * df.other.map(df2.vol) * df['corr']

哪个产量

df.head()


    ticker  other   corr        cov
1   CNP     F       0.302712    0.000056
2   CNP     GE      0.408604    0.000061
3   CNP     TSLA    0.205812    0.000070
4   CNP     WMT     0.289421    0.000042
5   F       CNP     0.302712    0.000056

当然你总是pivot_table可以像矩阵一样得到它

df.pivot_table(index=['ticker'], columns=['other'], values=['cov'], fill_value=1)


other   CNP         F          GE           TSLA        WMT
ticker                  
CNP     1.000000    0.000056    0.000061    0.000070    0.000042
F       0.000056    1.000000    0.000086    0.000117    0.000046
GE      0.000061    0.000086    1.000000    0.000089    0.000043
TSLA    0.000070    0.000117    0.000089    1.000000    0.000050
WMT     0.000042    0.000046    0.000043    0.000050    1.000000

或者使用.values获取对应的np.array

df.pivot_table(index=['ticker'], columns=['other'], values=['cov'], fill_value=1).values

array([[  1.00000000e+00,   5.62318492e-05,   6.05076457e-05,
          6.99435817e-05,   4.20812754e-05],
       [  5.62318492e-05,   1.00000000e+00,   8.57872875e-05,
          1.16723972e-04,   4.63723078e-05],
       [  6.05076457e-05,   8.57872875e-05,   1.00000000e+00,
          8.88688235e-05,   4.29291322e-05],
       [  6.99435817e-05,   1.16723972e-04,   8.88688235e-05,
          1.00000000e+00,   5.04454626e-05],
       [  4.20812754e-05,   4.63723078e-05,   4.29291322e-05,
          5.04454626e-05,   1.00000000e+00]])

推荐阅读