我在数据帧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
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]])
IIUC
df.set_index('ticker',inplace=True)
df=pd.DataFrame(s.values*s.values[:,None]*df.values)
df.values[[np.arange(len(df))]*2] = 1
df
Out[24]:
0 1 2 3 4
0 1.000000 0.000056 0.000061 0.000070 0.000042
1 0.000056 1.000000 0.000086 0.000117 0.000046
2 0.000061 0.000086 1.000000 0.000089 0.000043
3 0.000070 0.000117 0.000089 1.000000 0.000050
4 0.000042 0.000046 0.000043 0.000050 1.000000