Fill matrix with transposed version

I have a pairwise matrix:

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

I want to replace the NaN in the upper right corner with the same values ​​as in the lower left corner:

 >>> m2 abcd 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 can do this by replacing columns and indexes:

 cols = m.columns idxs = m.index for c in cols: for i in idxs: m[i][c] = m[c][i] 

But this is slow with my actual data, and I'm sure there is a way to do this in one step. I know that I can generate the upper right version with "mT", but I don’t know how to replace NaN with values ​​other than NaN to get the full matrix. There is probably a one-step way to do this in numpy, but I don't know from matrix algebra.

+6
source share
3 answers

How about ( docs ):

 >>> df.combine_first(df.T) abcd 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 
+4
source

Here is one alternative way:

 >>> m[np.triu_indices_from(m, k=1)] = mT[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)] returns values ​​above the diagonal m and assigns them to the values ​​above the diagonal transposition m .

+3
source

From numpy.isnan() :

 >>> m[np.isnan(m)] = mT[np.isnan(m)] >>> m abcd 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 

or better, panda.isnull() :

 >>> m[pd.isnull(m)] = mT[pd.isnull(m)] >>> m abcd 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 

which is finally equivalent to @DSM solution!

+1
source

Source: https://habr.com/ru/post/978521/


All Articles