使用 numpy 按另一个列表对矩阵的行和列进行排序

Luc*_*ijk 3 python numpy matrix

我有一个 NxN 方阵。这个矩阵通常很大(N 大约 5000),我想聚合这个矩阵的各个部分以形成一个更小的矩阵。

因此,我有一个包含 N 个元素的列表,这些元素表示新矩阵中应将哪些行/列分组在一起。

为了使算法更简单、更快,我想根据上面的列表对行和列进行排序。

例子:

输入 5x5 矩阵:

row/col |  1 |  2 |  3 |  4 |  5 |
      1 |  5 |  4 |  3 |  2 |  1 |
      2 | 10 |  9 |  8 |  7 |  6 |
      3 | 15 | 14 | 13 | 12 | 11 |
      4 | 20 | 19 | 18 | 17 | 16 |
      5 | 25 | 24 | 23 | 22 | 21 |
Run Code Online (Sandbox Code Playgroud)

需要明确的是:第一行是 [5 4 3 2 1],第一列是 [5, 10, 15, 20, 25]。

包含“标签”的列表,表示哪些行和列应在新矩阵中分组在一起:

[2 2 1 3 3]
Run Code Online (Sandbox Code Playgroud)

这意味着新矩阵将为 3x3(我们有 3 个不同的值)。

带有标签的矩阵:

labels             2       1      3
               --------- ---- ---------
      row/col |  1 |  2 |  3 |  4 |  5 |
   2 |      1 |  5 |  4 |  3 |  2 |  1 |
   2 |      2 | 10 |  9 |  8 |  7 |  6 |
   1 |      3 | 15 | 14 | 13 | 12 | 11 |
   3 |      4 | 20 | 19 | 18 | 17 | 16 |
   3 |      5 | 25 | 24 | 23 | 22 | 21 |
Run Code Online (Sandbox Code Playgroud)

预期排序矩阵:

row/col |  3 | 1 |  2 |  4 |  5 |
      3 | 13 |15 | 14 | 12 | 11 |
      1 |  3 | 5 |  4 |  2 |  1 |
      2 |  8 |10 |  9 |  7 |  6 |
      4 | 18 |20 | 19 | 17 | 16 |
      5 | 23 |25 | 24 | 22 | 21 |
Run Code Online (Sandbox Code Playgroud)

通过这个矩阵,我可以轻松地将分组元素相加,以形成 3x3 矩阵中的新元素。请注意,第三列和第三行已移动到前面/顶部,因为它的标签值较低(1 与 2 和 3)。

问题:如何使用 numpy 以这种方式对矩阵进行排序?我搜索了其他问题并找到了 lexsort、记录数组和其他东西,但作为一个没有太多 numpy 经验的人,我发现很难完成我想要的排序。

提前致谢!

Aka*_*all 5

numpy允许您对数组或列表进行索引,因此更改列和行的顺序很容易。

我想这就是您正在寻找的:

>>> a = np.arange(25).reshape(5,5)
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])   

  >>> a[[2,0,1,3,4]] [:,[2,0,1,3,4]]
array([[12, 10, 11, 13, 14],
       [ 2,  0,  1,  3,  4],
       [ 7,  5,  6,  8,  9],
       [17, 15, 16, 18, 19],
       [22, 20, 21, 23, 24]])
Run Code Online (Sandbox Code Playgroud)

作为旁注:

如果您只想更改行的顺序:

>>> a[[2,0,1,3,4]]
array([[10, 11, 12, 13, 14],
       [ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])
Run Code Online (Sandbox Code Playgroud)

如果您只想更改列的顺序:

>>> a[:,[2,0,1,3,4]] 
array([[ 2,  0,  1,  3,  4],
       [ 7,  5,  6,  8,  9],
       [12, 10, 11, 13, 14],
       [17, 15, 16, 18, 19],
       [22, 20, 21, 23, 24]])
Run Code Online (Sandbox Code Playgroud)