Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort rows and columns of a matrix by another list with numpy

I have a square NxN matrix. This matrix is often quite large (N around 5000), and I want to aggregate parts of this matrix to make a smaller matrix.

Therefore, I have a list with N elements, and these elemenets denote which rows/columns should be grouped together in the new matrix.

To make the algorithm a bit easier and faster, I want to sort the rows and columns based on the above list.

Example:

Input 5x5 matrix:

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 |

To be clear: the first row is [5 4 3 2 1] and the first column is [5, 10, 15, 20, 25].

The list containing the 'labels' which denote which rows and columns should be grouped together in the new matrix:

[2 2 1 3 3]

This means the new matrix will be 3x3 (we have 3 distinct values).

The matrix with the labels:

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 |

Expected sorted matrix:

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 |

And with this matrix I can easily sum the grouped elements to form a new element in the 3x3 matrix. Note that the third column and row has moved to the front/top, because it has a lower label value (1 versus 2 and 3).

The question: how to sort a matrix in this way with numpy? I've searched other questions and found lexsort, record arrays and other things, but as someone with not a lot of experience with numpy, I found it hard to accomplish the sorting I wanted.

Thanks in advance!

like image 501
Lucas van Dijk Avatar asked Oct 15 '25 14:10

Lucas van Dijk


1 Answers

numpy allows you to index over an array or list, thus changing order of columns and rows is easy.

I think this is what you are looking for:

>>> 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]])

As a side-note:

If you wanted to change order of just rows:

>>> 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]])

If you wanted to change order of just columns:

>>> 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]])
like image 62
Akavall Avatar answered Oct 18 '25 07:10

Akavall



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!