【问题标题】:How to sort a correlation matrix symmetrically?如何对相关矩阵进行对称排序?
【发布时间】:2017-12-18 05:58:42
【问题描述】:

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

举个例子,这是原始矩阵

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

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

【问题讨论】:

    标签: python arrays sorting matrix correlation


    【解决方案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])
    

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

    现在我们需要结合这两个数组来获得原始数组的排序+重新排列版本。当我们真正想要获得基本索引时,使用数组索引二维数组会触发花哨的索引,这会带来一点不便。所以我们需要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,并且仅通过将一个索引数组索引到另一个索引数组来索引右侧。我不确定这会比这种方法更清晰,所以我坚持使用这种方法。

    【讨论】:

    • 非常感谢。这很有意义
    • @ij1994 如果上述方法适用于您的应用程序,请告诉我。
    猜你喜欢
    • 2014-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多