2014-11-21 3 views
6

У меня есть парная матрица:заполняющая матрицы с транспонированной версией

>>> m 
    a b c d 
a 1.0 NaN NaN NaN 
b 0.5 1.0 NaN NaN 
c 0.6 0.0 1.0 NaN 
d 0.5 0.4 0.3 1.0 

Я хочу, чтобы заменить NaN в правом верхнем угле с теми же значениями, что и в левом нижнем углу:

>>> m2 
    a b c d 
a 1.0 0.5 0.6 0.5 
b 0.5 1.0 0.0 0.4 
c 0.6 0.0 1.0 0.3 
d 0.5 0.4 0.3 1.0 

I может сделать это путем замены столбцов и индексов:

cols = m.columns 
idxs = m.index 

for c in cols: 
    for i in idxs: 
     m[i][c] = m[c][i] 

Но это медленно с моими фактическими данными, и я уверен, что есть способ сделать это в один шаг. Я знаю, что могу сгенерировать верхнюю правую версию с «m.T», но я не знаю, как заменить NaN значениями, отличными от NaN, чтобы получить полную матрицу. Вероятно, есть одноэтапный способ сделать это в numpy, но я не знаю из матричной алгебры.

ответ

4

Как насчет (docs):

>>> df.combine_first(df.T) 
    a b c d 
a 1.0 0.5 0.6 0.5 
b 0.5 1.0 0.0 0.4 
c 0.6 0.0 1.0 0.3 
d 0.5 0.4 0.3 1.0 
3

Вот один альтернативный способ:

>>> m[np.triu_indices_from(m, k=1)] = m.T[np.triu_indices_from(m, k=1)] 
>>> m 
array([[ 1. , 0.5, 0.6, 0.5], 
     [ 0.5, 1. , 0. , 0.4], 
     [ 0.6, 0. , 1. , 0.3], 
     [ 0.5, 0.4, 0.3, 1. ]]) 

m[np.triu_indices_from(m, k=1)] возвращает значения выше диагонали m и присваивает им значения значений выше диагонали транспонированной m.

1

С numpy.isnan():

>>> m[np.isnan(m)] = m.T[np.isnan(m)] 
>>> m 
    a b c d 
a 1.0 0.5 0.6 0.5 
b 0.5 1.0 0.0 0.4 
c 0.6 0.0 1.0 0.3 
d 0.5 0.4 0.3 1.0 

или лучше, с panda.isnull():

>>> m[pd.isnull(m)] = m.T[pd.isnull(m)] 
>>> m 
    a b c d 
a 1.0 0.5 0.6 0.5 
b 0.5 1.0 0.0 0.4 
c 0.6 0.0 1.0 0.3 
d 0.5 0.4 0.3 1.0 

, который, наконец, эквивалентно решению @DSM «s !