将NumPy矩阵不同值部分的上下三角提取到2列

2024-09-28 01:23:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个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

我可以用两部分提取上面的数据帧(我首先提取上面的三角形,然后提取下面的三角形):

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

但是当我创建一个数据帧时,我有一堆代码,要提取上面正确的数据帧非常复杂

我能提取一次吗

更新解决方案

Mr/Ms-Pygirl给出了一个很好的解决方案,但是当您的矩阵具有值0时:

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

Pygirl解决方案将给出一个结果:

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-SOLUTION后)

我有一个具有4x4维度的test_matrix

    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

Tags: 数据testdfnptriangularnan解决方案upper
2条回答

代码设置:

import pandas as pd
import numpy as np

test_matrix = np.array([[np.nan,10,20],[30,np.nan,40],[50,60,np.nan]])

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

lower_triangular = list(np.tril(test_matrix).flat)
upper_triangular = list(np.triu(test_matrix).flat)

lower_triangular = [x for x in lower_triangular if x>0]
upper_triangular = [x for x in upper_triangular if x>0]


cus1 = np.tril_indices(test_matrix.shape[0], -1)[0]
cus2 = np.tril_indices(test_matrix.shape[0], -1)[1]

q = pd.DataFrame(
    {'cus1': cus1,
     'cus2': cus2,
     'lower': lower_triangular,
     'upper': upper_triangular
    })

输出:

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

尝试:

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

相关问题 更多 >

    热门问题