如何对称排序相关矩阵?

时间:2017-07-13 12:37:54

标签: python arrays sorting matrix correlation

我正在处理相关矩阵,我想重新排列行和列,以便平均相关性最高的列位于中间,第二个最好是高于该值的一个索引,第三个是低于中间的一个索引, 等等等等。

在一个例子中,这是原始矩阵

[[ 1.        , -0.85240671,  0.93335528,  0.75431679,  0.81586527],
 [-0.85240671,  1.        , -0.874545  , -0.68551567, -0.8594703 ],
 [ 0.93335528, -0.874545  ,  1.        ,  0.7103762 ,  0.86104527],
 [ 0.75431679, -0.68551567,  0.7103762 ,  1.        ,  0.73345121],
 [ 0.81586527, -0.8594703 ,  0.86104527,  0.73345121,  1.        ]]

理想情况下,新的列/行顺序(使用python索引)是3,1,2,0,4。所以它看起来像

[[1,-.686,.710,.754,.733], 
 [-.686,1,-.875,-.852,-.859], 
 [.710,-.875,1,.933,.861], 
 [.754,-.852,.754,1,.816], 
 [.733,-.859,.861,.816,1]]

我所知道的排序算法似乎都没有能够处理我的“对称性”目标。我正在使用numpy作为我的矩阵。

有些矩阵不会有奇怪的尺寸,所以如果可能的话,我还想要一种方法来处理具有偶数的矩阵。任何帮助都会很棒。

1 个答案:

答案 0 :(得分:1)

我不确定你的问题中“确定最大相关性的顺序”部分,但这不是问题的核心。

我认为,假设您的数组被称为arr,确定降序相关的顺序可以通过

完成
corrs = arr.sum(axis=0)
corr_order = corrs.argsort()[::-1] 

但问题的主要部分是在这个特定的“中间最大”顺序中填写矩阵。必须有一种更优雅的方式,但这是我在列排序递减后获取列顺序时所做的:

ndim = arr.shape[0]
inds_orig = list(range(ndim))
inds = []
for _ in range(ndim):
    inds.append(inds_orig[(len(inds_orig)-1)//2])
    del inds_orig[(len(inds_orig)-1)//2]
inds = np.array(inds)

现在,ndim=5的上述内容将为我们提供

array([2, 1, 3, 0, 4])

这似乎正是你想要的:中间的第一个(最大)列,然后是交替两侧的每个后续项目。

现在我们需要将这两个数组组合起来,以获得原始数组的排序+重新排列版本。当我们真的想要获得基本索引时,使用数组索引你的2d数组会引发花哨的索引会有一点点不便。因此,我们需要np.ix_将我们的花式索引转换为等效的有效切片:

res = np.empty_like(arr)
res[np.ix_(inds,inds)] = arr[np.ix_(corr_order,corr_order)]

结果是

array([[ 1.        ,  0.7103762 ,  0.75431679,  0.73345121, -0.68551567],
       [ 0.7103762 ,  1.        ,  0.93335528,  0.86104527, -0.874545  ],
       [ 0.75431679,  0.93335528,  1.        ,  0.81586527, -0.85240671],
       [ 0.73345121,  0.86104527,  0.81586527,  1.        , -0.8594703 ],
       [-0.68551567, -0.874545  , -0.85240671, -0.8594703 ,  1.        ]])

在我的“最大相关性”定义中检查此矩阵是否正确:

>>> print(res.sum(axis=0))
[ 2.51262853  2.63023175  2.65113063  2.55089145 -2.27193768]

正如你所看到的那样:中间最大,然后一个在左边,然后一个在右边,然后是第一个,然后是最后一个。

除非我弄错了,否则另一个选项将是左侧的invert the sorting permutation,而右侧的索引只能通过将一个索引数组索引到另一个索引数组中。我不确定那会比这种方法更清楚,所以我坚持这个。