在矩阵mat n x n的情况下,我可以执行以下操作
sym = 0.5 * (mat + mat.T)
该操作给出了期望的结果sym [i,j] = sym [j,i]
假设我们有一个3D数组ndarr [i,j,k],其中i,j,k 0,1,... n, 然后ndarr是n x n x n。想法是获得以下“对称”形式 nsym [i,j,k] = nsym [j,i,k]使用ndarr。我试过这个:
import numpy as np
# Generate some random matrix, n = 5
ndarr = np.random.beta(0.1,1,(5,5,5))
# First attempt to symmetrize
sym1 = np.array([0.5*(ndarr[:,:,k]+ndarr[:,:,k].T) for k in range(5)])
这里的问题是sym1 [i,j,k]!= sym1 [j,i,k],因为它是必需的。实际上我获得了sym1 [i,j,k] = sym1 [i,k,j],在最后两个符号的交换下对称!
# Second attempt
sym2 = 0.5*(ndarr+ndarr.T)
这里的问题相同,sym2与第二个索引sym2 [i,j,k] = sym2 [k,j,i]对称。
要恢复,目标是找到相对于第三个索引的3D数组的对称形式,并保留原始ndarr [i,i,i]的对角线值。
答案 0 :(得分:3)
这里的问题是你没有使用正确的转置:
sym = 0.5 * (ndarr + np.transpose(ndarr, (1, 0, 2)))
默认情况下,np.transpose
和.T
属性将颠倒轴的顺序。在您的情况下,我们只想翻转前两个轴:(0,1,2) -> (1,0,2)
。
编辑:您首次尝试失败的原因是因为您沿着第一个轴而不是最后一个轴连接每个对称矩阵。如果您使用ndarr
形状(5, 5, 3)
,则会更清楚:
In [16]: sym = np.array([0.5*(ndarr[:,:,k]+ndarr[:,:,k].T) for k in range(3)])
In [17]: sym.shape
Out[17]: (3L, 5L, 5L)
无论如何,np.transpose
上面的版本更清晰,效率更高。