获取相关矩阵的唯一组合值 - pandas

5

假设我有一个看起来像这样的相关矩阵:

df = pd.DataFrame(data={'a':[1,0.2,0.3,0.4],'b':[0.2,1,0.5,0.6],'c':[0.3,0.5,1,0.7],'d':[0.4,0.6,0.7,1]}, index=['a','b','c','d'])

什么是提取每个成对组合(a-b、a-c等)的唯一值的最佳方法?
df2 =
      a_b  a_c  a_d  b_c  b_d  c_d 
      0.2  0.3  0.4  0.5  0.6  0.7

我唯一能想到的方法就是编写自己的函数,但想知道是否有更简便的方法。


为了仅获取相关性,可以使用以下代码:df.values[np.triu_indices(len(df), 1)]。这假设df是一个方形的相关性数据框。请参见下面的答案。 - william_grisaitis
4个回答

10

IIUC:

df_out = df.stack()
df_out.index = df_out.index.map('_'.join)
df_out = df_out.to_frame().T

输出:

   a_a  a_b  a_c  a_d  b_a  b_b  b_c  b_d  c_a  c_b  c_c  c_d  d_a  d_b  d_c  
0  1.0  0.2  0.3  0.4  0.2  1.0  0.5  0.6  0.3  0.5  1.0  0.7  0.4  0.6  0.7   

如果你想要去掉a_a、b_b等字符……

df_out = df.stack()
df_out = df_out[df_out.index.get_level_values(0) != df_out.index.get_level_values(1)]
df_out.index = df_out.index.map('_'.join)
df_out = df_out.to_frame().T

输出

   a_b  a_c  a_d  b_a  b_c  b_d  c_a  c_b  c_d  d_a  d_b  d_c
0  0.2  0.3  0.4  0.2  0.5  0.6  0.3  0.5  0.7  0.4  0.6  0.7

或者是想要去掉b_a并保留a_b:

df_out = df.stack()
df_out = df_out[df_out.index.get_level_values(0) < df_out.index.get_level_values(1)]
df_out.index = df_out.index.map('_'.join)
df_out = df_out.to_frame().T

或者在 .loc 中使用 lambda 函数来合并几行:

df_out = df.stack().loc[lambda x: x.index.get_level_values(0) < x.index.get_level_values(1)]
df_out.index = df_out.index.map('_'.join)
df_out = df_out.to_frame().T

输出:

   a_b  a_c  a_d  b_c  b_d  c_d
0  0.2  0.3  0.4  0.5  0.6  0.7

1
谢谢,这很好用!我知道一定有比写自己的函数更优雅的方法。非常感谢! - HappyPy

4

如果我没记错,你可以操作索引

df2 = df.unstack().reset_index()
s = df2[['level_0', 'level_1']].agg(frozenset,1).drop_duplicates()
df2 = df2.loc[s.index]
ind = df2.agg(lambda k:  (k['level_0']+'_'+k['level_1']), axis=1)
df2.set_index(ind)[0].to_frame().T

    a_a a_b a_c a_d b_b b_c b_d c_c c_d d_d
0   1.0 0.2 0.3 0.4 1.0 0.5 0.6 1.0 0.7 1.0

1
你可以有效地使用矩阵:
import numpy as np
df = pd.DataFrame(data={'a':[1,0.2,0.3,0.4],'b':[0.2,1,0.5,0.6],'c':[0.3,0.5,1,0.7],'d':[0.4,0.6,0.7,1]}, index=['a','b','c','d'])
unique_values=[s for s in np.tril(df, k=-1).flatten() if s!=0]
print(unique_values)

它给你: [0.2, 0.3, 0.5, 0.4, 0.6, 0.7]

关键在于np.tril函数。


0
如果相关性是 corrs (例如来自 corrs = df.corr()),则唯一的相关值为:
upper_right_entries = np.triu_indices(len(corrs), 1)
corrs.values[upper_right_entries]

这里使用了numpy.triu_indices,它会生成一个索引列表,以获取2D数组中所有右上角的元素。参数1排除了主对角线(在相关矩阵中为1.0)。

感谢@Ji Ma提供的使用np.tril的答案。我认为我的解决方案更简洁易懂。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接