从 pandas 中的相关矩阵返回最高和最低相关
Returning the highest and lowest correlations from a correlation matrix in pandas
我有一堆股票数据,我正在尝试构建一个数据框,从相关矩阵中获取前两个和底部的股票,以及它们的实际相关性。
假设矩阵,corr
看起来像这样:
A B C D E
A 1.00 0.65 0.31 0.94 0.55
B 0.87 1.00 0.96 0.67 0.41
C 0.95 0.88 1.00 0.72 0.69
D 0.64 0.84 0.99 1.00 0.78
E 0.71 0.62 0.89 0.32 1.00
我想做的是 return 股票 A、B、C、D 和 E 的最好的两只和最不相关的股票,以及它们的相关性,同时放弃明显的每只股票与自身的相关性为 1.00。
生成的数据框,或任何最容易显示的数据框,将如下所示:
Stock 1st 1st_Val 2nd 2nd_Val Last Last_Val
A D 0.94 B 0.65 C 0.31
B C 0.96 A 0.87 E 0.41
C A 0.95 B 0.88 E 0.69
D C 0.99 B 0.84 A 0.64
E C 0.89 A 0.71 D 0.32
到目前为止,我已经能够使用 corr[stock].nlargest().index[0:].tolist()
查看并 return 相关股票名称,然后使用 [1]
、[2]
和 [-1]
来自每个列表并将它们粘贴在字典中并从那里构建数据框。但是我无法 return 相关值,我怀疑我没有以最有效的方式这样做。
非常感谢任何帮助,干杯
您的条件很难归纳为一条命令,但您可以采用以下一种方法。
删除对角线
import numpy as np
np.fill_diagonal(corr.values, np.nan)
print(corr)
# A B C D E
#A NaN 0.65 0.31 0.94 0.55
#B 0.87 NaN 0.96 0.67 0.41
#C 0.95 0.88 NaN 0.72 0.69
#D 0.64 0.84 0.99 NaN 0.78
#E 0.71 0.62 0.89 0.32 NaN
查找前 2 列和后列名称
您可以使用 上的答案来获取每行(股票)的前 2 个值和后一个值。
order_top2 = np.argsort(-corr.values, axis=1)[:, :2]
order_bottom = np.argsort(corr.values, axis=1)[:, :1]
result_top2 = pd.DataFrame(
corr.columns[order_top2],
columns=['1st', '2nd'],
index=corr.index
)
result_bottom = pd.DataFrame(
corr.columns[order_bottom],
columns=['Last'],
index=corr.index
)
result = result_top2.join(result_bottom)
# 1st 2nd Last
#A D B C
#B C A E
#C A B E
#D C B A
#E C A D
现在使用pandas.DataFrame.lookup
为result
中的每一列获取corr
中对应的列值
for x in result.columns:
result[x+"_Val"] = corr.lookup(corr.index, result[x])
print(result)
# 1st 2nd Last 1st_Val 2nd_Val Last_Val
#A D B C 0.94 0.65 0.31
#B C A E 0.96 0.87 0.41
#C A B E 0.95 0.88 0.69
#D C B A 0.99 0.84 0.64
#E C A D 0.89 0.71 0.32
重新排序列(可选)
print(result[['1st', '1st_Val', '2nd', '2nd_Val', 'Last', 'Last_Val']])
# 1st 1st_Val 2nd 2nd_Val Last Last_Val
#A D 0.94 B 0.65 C 0.31
#B C 0.96 A 0.87 E 0.41
#C A 0.95 B 0.88 E 0.69
#D C 0.99 B 0.84 A 0.64
#E C 0.89 A 0.71 D 0.32
如果您需要可视化结果但实际上不需要获取和使用实际相关值,那么为什么不使用非常简单的 heatmap?您还可以玩这个情节,让数字显示在每个方块上。
import seaborn as sns
import pandas as pd
dict = {'Date':['2018-01-01','2018-01-02','2018-01-03','2018-01-04','2018-01-05'],'Col1':[1,2,3,4,5],'Col2':[1.1,1.2,1.3,1.4,1.5],'Col3':[0.33,0.98,1.54,0.01,0.99],'Col4':[8,9.98,6,0.01,0.1],'Col1':[19,42,3,0.4,51]}
df = pd.DataFrame(dict, columns=dict.keys())
sns.heatmap(df.corr())
更多依赖 modern pandas style 的不同答案。第二大相关性我没有找到很好的解法。我会在找到答案后进行编辑。
### Create an example df
df = pd.DataFrame(data = {"A":pd.np.random.randn(10),
"B":pd.np.random.randn(10),
"C":pd.np.random.randn(10),
"D":pd.np.random.randn(10),
}
)
# Solution
(
df.corr() #correlation matrix
.replace(1, pd.np.nan) # replace the matrix with nans
.assign( # assign new variables
First = lambda x: x.loc[["A","B","C","D"], ["A","B","C","D"]].idxmax(axis = 1), # Biggest correlation idx
First_value = lambda x: x.loc[["A","B","C","D"], ["A","B","C","D"]].max(axis = 1), # Biggest correlation
Last = lambda x: x.loc[["A","B","C","D"],["A","B","C","D"]].idxmin(axis = 1), # Smallest correlation idx
Last_value = lambda x: x.loc[["A","B","C","D"],["A","B","C","D"]].idxmin(axis = 1), # Smallest correlation
)
)
我使用 .loc[["A","B","C","D"],["A","B","C","D"]]
以便仅在未修改的数据帧上进行操作。
输出:
A B C D First First_value Last Last_value
A NaN -0.085776 -0.203110 -0.003450 D -0.003450 C C
B -0.085776 NaN -0.110402 0.687283 D 0.687283 C C
C -0.203110 -0.110402 NaN 0.017644 D 0.017644 A A
D -0.003450 0.687283 0.017644 NaN B 0.687283 A A
corr.unstack().min()
-> 求值
corr.unstack().idxmin()
-> 查找索引
我有一堆股票数据,我正在尝试构建一个数据框,从相关矩阵中获取前两个和底部的股票,以及它们的实际相关性。
假设矩阵,corr
看起来像这样:
A B C D E
A 1.00 0.65 0.31 0.94 0.55
B 0.87 1.00 0.96 0.67 0.41
C 0.95 0.88 1.00 0.72 0.69
D 0.64 0.84 0.99 1.00 0.78
E 0.71 0.62 0.89 0.32 1.00
我想做的是 return 股票 A、B、C、D 和 E 的最好的两只和最不相关的股票,以及它们的相关性,同时放弃明显的每只股票与自身的相关性为 1.00。
生成的数据框,或任何最容易显示的数据框,将如下所示:
Stock 1st 1st_Val 2nd 2nd_Val Last Last_Val
A D 0.94 B 0.65 C 0.31
B C 0.96 A 0.87 E 0.41
C A 0.95 B 0.88 E 0.69
D C 0.99 B 0.84 A 0.64
E C 0.89 A 0.71 D 0.32
到目前为止,我已经能够使用 corr[stock].nlargest().index[0:].tolist()
查看并 return 相关股票名称,然后使用 [1]
、[2]
和 [-1]
来自每个列表并将它们粘贴在字典中并从那里构建数据框。但是我无法 return 相关值,我怀疑我没有以最有效的方式这样做。
非常感谢任何帮助,干杯
您的条件很难归纳为一条命令,但您可以采用以下一种方法。
删除对角线
import numpy as np
np.fill_diagonal(corr.values, np.nan)
print(corr)
# A B C D E
#A NaN 0.65 0.31 0.94 0.55
#B 0.87 NaN 0.96 0.67 0.41
#C 0.95 0.88 NaN 0.72 0.69
#D 0.64 0.84 0.99 NaN 0.78
#E 0.71 0.62 0.89 0.32 NaN
查找前 2 列和后列名称
您可以使用
order_top2 = np.argsort(-corr.values, axis=1)[:, :2]
order_bottom = np.argsort(corr.values, axis=1)[:, :1]
result_top2 = pd.DataFrame(
corr.columns[order_top2],
columns=['1st', '2nd'],
index=corr.index
)
result_bottom = pd.DataFrame(
corr.columns[order_bottom],
columns=['Last'],
index=corr.index
)
result = result_top2.join(result_bottom)
# 1st 2nd Last
#A D B C
#B C A E
#C A B E
#D C B A
#E C A D
现在使用pandas.DataFrame.lookup
为result
corr
中对应的列值
for x in result.columns:
result[x+"_Val"] = corr.lookup(corr.index, result[x])
print(result)
# 1st 2nd Last 1st_Val 2nd_Val Last_Val
#A D B C 0.94 0.65 0.31
#B C A E 0.96 0.87 0.41
#C A B E 0.95 0.88 0.69
#D C B A 0.99 0.84 0.64
#E C A D 0.89 0.71 0.32
重新排序列(可选)
print(result[['1st', '1st_Val', '2nd', '2nd_Val', 'Last', 'Last_Val']])
# 1st 1st_Val 2nd 2nd_Val Last Last_Val
#A D 0.94 B 0.65 C 0.31
#B C 0.96 A 0.87 E 0.41
#C A 0.95 B 0.88 E 0.69
#D C 0.99 B 0.84 A 0.64
#E C 0.89 A 0.71 D 0.32
如果您需要可视化结果但实际上不需要获取和使用实际相关值,那么为什么不使用非常简单的 heatmap?您还可以玩这个情节,让数字显示在每个方块上。
import seaborn as sns
import pandas as pd
dict = {'Date':['2018-01-01','2018-01-02','2018-01-03','2018-01-04','2018-01-05'],'Col1':[1,2,3,4,5],'Col2':[1.1,1.2,1.3,1.4,1.5],'Col3':[0.33,0.98,1.54,0.01,0.99],'Col4':[8,9.98,6,0.01,0.1],'Col1':[19,42,3,0.4,51]}
df = pd.DataFrame(dict, columns=dict.keys())
sns.heatmap(df.corr())
更多依赖 modern pandas style 的不同答案。第二大相关性我没有找到很好的解法。我会在找到答案后进行编辑。
### Create an example df
df = pd.DataFrame(data = {"A":pd.np.random.randn(10),
"B":pd.np.random.randn(10),
"C":pd.np.random.randn(10),
"D":pd.np.random.randn(10),
}
)
# Solution
(
df.corr() #correlation matrix
.replace(1, pd.np.nan) # replace the matrix with nans
.assign( # assign new variables
First = lambda x: x.loc[["A","B","C","D"], ["A","B","C","D"]].idxmax(axis = 1), # Biggest correlation idx
First_value = lambda x: x.loc[["A","B","C","D"], ["A","B","C","D"]].max(axis = 1), # Biggest correlation
Last = lambda x: x.loc[["A","B","C","D"],["A","B","C","D"]].idxmin(axis = 1), # Smallest correlation idx
Last_value = lambda x: x.loc[["A","B","C","D"],["A","B","C","D"]].idxmin(axis = 1), # Smallest correlation
)
)
我使用 .loc[["A","B","C","D"],["A","B","C","D"]]
以便仅在未修改的数据帧上进行操作。
A B C D First First_value Last Last_value
A NaN -0.085776 -0.203110 -0.003450 D -0.003450 C C
B -0.085776 NaN -0.110402 0.687283 D 0.687283 C C
C -0.203110 -0.110402 NaN 0.017644 D 0.017644 A A
D -0.003450 0.687283 0.017644 NaN B 0.687283 A A
corr.unstack().min()
-> 求值
corr.unstack().idxmin()
-> 查找索引