首页 > 解决方案 > 将 NumPy 矩阵的具有不同值部分的上下三角形提取到 2 列熊猫

问题描述

我有一个test_matrix

    A  B  C
A  nan 10 20
B  30 nan 40
C  50 60 nan

我的数据框应该是:

cus1    cus2    lower    upper
 A       B       30       10
 A       C       50       20
 B       C       60       40

我可以用 2 个部分提取上面的 DataFrame(我先提取上部,然后提取下部三角形):

lower_triangular = test_matrix[np.tril_indices(test_matrix.shape[0], -1)]
upper_triangular = test_matrix[np.triu_indices(test_matrix.shape[0], 1)]

但是当我创建一个DataFrame时,我有一堆代码非常复杂,无法提取上面的正确DataFrame。

我可以提取一次吗?

更新解决方案

Mr/Ms Pygirl提供了一个很好的解决方案,但是当您的矩阵具有价值时0

    A   B   C
A  nan 10   0
B  30  nan  40
C  0   60  nan

Pygirl-solution 将给出结果:

cus1    cus2    lower    upper
A       B       30       10
B       C       60       40

如果你想得到一个值0(索引:ACCA),你应该使用:

df2=df.where(np.triu(np.ones(df.shape)).astype(np.bool)).stack().rename_axis(('cus1', 'cus2')).reset_index(name='upper')

y=df.where(np.tril(np.ones(df.shape)).astype(np.bool)).stack().values

结果:

cus1    cus2    lower    upper
A       B       30       10
A       C       0        0
B       C       60       40

问题2(使用PYGIRL-解决方案后)

我有一个test_matrix4x4 尺寸:

    A    B    C    D
A  nan   10   20   30 
B  40    nan  50   60
C  70    80   nan  90
D  100   110  120  nan

我的数据框应该是:

cus1    cus2    lower    upper
 A       B       40       10
 A       C       70       20
 A       D       100      30
 B       C       80       50
 B       D       110      60
 D       C       120      90

但我得到了错误的结果(丢失的 DC 和错误的 AD、BC):

cus1    cus2    lower    upper
 A       B       40       10
 A       C       70       20
 A       D       *80*     *30*
 B       C       *100*    *50*
 B       D       110      60

标签: pythonpandasdataframenumpy

解决方案


尝试:

li = ['A', 'B' , 'C']
df = pd.DataFrame(test_matrix, index=li, columns=li)
    
df2=df.where(np.triu(df).astype(np.bool)).stack().rename_axis(('cus1', 'cus2')).reset_index(name='upper')
y=df.where(np.tril(df).astype(np.bool)).stack().values#.reset_index(name='upper')
df2['lower'] = y

df2:

    cus1    cus2    upper   lower
0   A       B       10.0    30.0
1   A       C       20.0    50.0
2   B       C       40.0    60.0

编辑:

df = pd.DataFrame(test_matrix, index=li, columns=li)
    
df2=df.where(np.triu(df).astype(np.bool)).stack().rename_axis(('cus1', 'cus2')).reset_index(name='upper')
df1=df.where(np.tril(df).astype(np.bool)).stack().rename_axis(('cus2', 'cus1')).reset_index(name='lower')
df3 = pd.merge(df1,df2,on=['cus2', 'cus1'])

df3:

  cus2 cus1 lower   upper
0   B   A   40.0    10.0
1   C   A   70.0    20.0
2   C   B   80.0    50.0
3   D   A   100.0   30.0
4   D   B   110.0   60.0
5   D   C   120.0   90.0


推荐阅读