user4555363 user4555363 - 8 days ago 6
Python Question

NumPy: sort matrix rows by number of non-zero entries

import numpy as np

def calc_size(matrix, index):
return np.nonzero(matrix[index,:])[1].size

def swap_rows(matrix, frm, to):
matrix[[frm, to],:] = matrix[[to, frm],:]


Numpy - Python 2.7

How can I achieve that matrix's rows are sorted after the size of the nonzero entries? I already wrote these two methods for doing the work but I need to give it to a sorting engine? The fullest rows should be at the beginning!

Answer

If you have an array arr:

array([[0, 0, 0, 0, 0],
       [1, 0, 1, 1, 1],
       [0, 1, 0, 1, 1],
       [1, 1, 1, 1, 1]])

You could sort the array's rows according to the number of zero entries by writing:

>>> arr[(arr == 0).sum(axis=1).argsort()]
array([[1, 1, 1, 1, 1],
       [1, 0, 1, 1, 1],
       [0, 1, 0, 1, 1],
       [0, 0, 0, 0, 0]])

This first counts the number of zero entries in each row with (arr == 0).sum(axis=1): this produces the array [5, 1, 2, 0].

Next, argsort sorts the indices of this array by their corresponding value, giving [3, 1, 2, 0].

Lastly, this argsorted array is used to rearrange the rows of arr.

P.S. If you have a matrix m (and not an array), you may need to ravel before using argsort:

m[(m == 0).sum(axis=1).ravel().argsort()]
Comments