2015-12-22 4 views
13

Учитывая квадрат панды DataFrame следующего вида:Растопить Верхняя треугольная матрица Панды Dataframe

a b c 
a 1 .5 .3 
b .5 1 .4 
c .3 .4 1 

Как я могу melt только верхний треугольник, чтобы получить

Row  Column Value 
    a  a  1 
    a  b  .5 
    a  c  .3 
    b  b  1 
    b  c  .4 
    c  c  1 

#Note the combination a,b is only listed once. There is no b,a listing  

Я больше заинтересованный в идиоматическом решении pandas, пользовательский индексатор был бы достаточно лёгким для записи вручную ... Спасибо за ваше внимание и ответ.

ответ

18

Сначала я конвертировать более низкие значения df в NaN по where и numpy.triu, а затем stack, reset_index и установить имена столбцов:

import numpy as np 

print df 
    a b c 
a 1.0 0.5 0.3 
b 0.5 1.0 0.4 
c 0.3 0.4 1.0 

print np.triu(np.ones(df.shape)).astype(np.bool) 
[[ True True True] 
[False True True] 
[False False True]] 

df = df.where(np.triu(np.ones(df.shape)).astype(np.bool)) 
print df 
    a b c 
a 1 0.5 0.3 
b NaN 1.0 0.4 
c NaN NaN 1.0 

df = df.stack().reset_index() 
df.columns = ['Row','Column','Value'] 
print df 

    Row Column Value 
0 a  a 1.0 
1 a  b 0.5 
2 a  c 0.3 
3 b  b 1.0 
4 b  c 0.4 
5 c  c 1.0 
+2

Единственное, на что можно обратить внимание, это то, что у вас есть какие-либо значения «NaN», которые вы хотите сохранить в верхнем треугольнике ('stack' будет их бросать). Возможно, вам придется явно построить мультииндекс, а затем переиндексировать, если это так. –

4

Строительства из раствора @jezrael, булева индексация будет более явным подходом:

import numpy 
from pandas import DataFrame 

df = DataFrame({'a':[1,.5,.3],'b':[.5,1,.4],'c':[.3,.4,1]},index=list('abc')) 
print df,'\n' 
keep = np.triu(np.ones(df.shape)).astype('bool').reshape(df.size) 
print df.stack()[keep] 

выход:

 a b c 
a 1.0 0.5 0.3 
b 0.5 1.0 0.4 
c 0.3 0.4 1.0 

a a 1.0 
    b 0.5 
    c 0.3 
b b 1.0 
    c 0.4 
c c 1.0 
dtype: float64 
Смежные вопросы