2014-11-21 16 views
6

Mam parami matrycy:matryca Fill z transponowana wersji

>>> 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 

Chcę wymienić NaN w prawym górnym rogu z tymi samymi wartościami jak w lewym dolnym rogu:

>>> 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 można to zrobić, zamieniając kolumny i indeksy:

cols = m.columns 
idxs = m.index 

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

Ale to jest powolne z moich rzeczywistych danych, i jestem pewien, że jest sposób, aby to zrobić w jeden krok. Wiem, że mogę wygenerować wersję górną prawą z "m.T", ale nie wiem jak zastąpić NaN wartościami innymi niż NaN, aby uzyskać kompletną macierz. Prawdopodobnie jest to jeden krok w numpy, ale nie wiem z algebry macierzy.

Odpowiedz

4

Jak o (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

Oto jeden alternatywny sposób:

>>> 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)] zwraca wartości powyżej przekątnej m i przypisuje je do wartości wartości powyżej przekątnej transpozycją m.

1

z 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 

lub lepiej z 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 

który ostatecznie równoważne rozwiązania @DSM jest !