我有一个成对矩阵:
>>> 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
我可以通过交换列和索引来实现:
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中可能只有一步到位的方法,但我不知道矩阵代数。
答案 0 :(得分: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
答案 1 :(得分: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
转置对角线以上的值。
答案 2 :(得分: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的解决方案!