I have a test_matrix:
A B C
A nan 10 20
B 30 nan 40
C 50 60 nan
My DataFrame should be:
cus1 cus2 lower upper
A B 30 10
A C 50 20
B C 60 40
I can extract DataFrame above with 2 parts (I extract the upper is first and the lower triangular is second):
lower_triangular = test_matrix[np.tril_indices(test_matrix.shape[0], -1)]
upper_triangular = test_matrix[np.triu_indices(test_matrix.shape[0], 1)]
But when I create a DataFrame, I have a bunch of code is very complex to extract right DataFrame above.
Can I extract it one times?
UPDATE SOLUTION
Mr/Ms Pygirl give a good solution, but when your matrix has value 0:
A B C
A nan 10 0
B 30 nan 40
C 0 60 nan
Pygirl-solution will give a result:
cus1 cus2 lower upper
A B 30 10
B C 60 40
If you want to get a value 0 (index: AC and CA), you should use:
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
The result:
cus1 cus2 lower upper
A B 30 10
A C 0 0
B C 60 40
PROBLEM 2 (AFTER USE PYGIRL-SOLUTION)
I have a test_matrix with 4x4 dimension:
A B C D
A nan 10 20 30
B 40 nan 50 60
C 70 80 nan 90
D 100 110 120 nan
My DataFrame should be:
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
But I get a wrong result (lost DC and wrong 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