Sorting an array in Python without changing the position of certain elements

I have a numpy array in Python that is n-by-n (in a 3-by-3 example) and contains null values ​​in all diagonal positions. eg

array([[ 0. , -0.65 , 1.3 , 0.56], [ 0.45 , 0. , 0.54, 43 ], [ 0.5 , 0.12 , 0. , 7 ] [ 0.2 , 0.3 , 0.4 , 0 ]]) 

Is it possible to sort an array without changing the diagonal positions to look like the one shown below? Since all sorting functions will take into account the "zeros" that exist in diagonal positions and change their relative position.

 array([[ 0. , 1.3 , 0.56 , -0.65], [ 43 , 0. , 0.54 , 0.45 ], [ 7 , 0.5 , 0. , 0.12 ] [ 0.4 , 0.3 , 0.2 , 0 ]]) 

If the above operation cannot be performed, then the maximum values ​​of N and their corresponding indices in each row may be sufficient.

So far I have tried sorting and argsort, but with no result.

+5
source share
2 answers

The easiest way is to remove zeros, sort, and then add zeros back diagonally:

 >>> a = [[0,1,2],[3,0,0],[5,6,0]] >>> no_zeroes = [r[:i] + r[i+1:] for i, r in enumerate(a)] >>> no_zeroes [[1, 2], [3, 0], [5, 6]] >>> sorted_no_zeroes = [sorted(r, reverse=True) for r in no_zeroes] >>> sorted_no_zeroes [[2, 1], [3, 0], [6, 5]] >>> sorted_with_zeroes = [r[:i] + [0] + r[i:] for i, r in enumerate(sorted_no_zeroes)] >>> sorted_with_zeroes [[0, 2, 1], [3, 0, 0], [6, 5, 0]] 

Completed into function:

 >>> def sort_ignoring_zeroes(a): ... s = [sorted(r[:i] + r[i+1:], reverse=True) for i, r in enumerate(a)] ... return [r[:i] + [0] + r[i:] for i, r in enumerate(s)] ... >>> sort_ignoring_zeroes( [[ 0. , 1.3 , 0.56 , -0.65], ... [ 43 , 0. , 0.54 , 0.45], ... [ 7 , 0.5 , 0. , 0.12]]) [[0, 1.3, 0.56, -0.65], [43, 0, 0.54, 0.45], [7, 0.5, 0, 0.12]] >>> 
+1
source

I'm a little late to this question, but if you are looking for a solution only for NumPy, you can replace inf with your diagonal, sort in the selected order and then shuffle the inf column back to the diagonal:

 In [189]: a = np.array([[ 0. , -0.65 , 1.3 , 0.56], .....: [ 0.45 , 0. , 0.54, 43 ], .....: [ 0.5 , 0.12 , 0. , 7 ], .....: [ 0.2 , 0.3 , 0.4 , 0 ]]) In [190]: np.fill_diagonal(a,np.inf) In [191]: a.sort() In [192]: a = a[:,::-1] In [193]: for i in range(1,len(a)): .....: a[i,:i+1] = np.roll(a[i,:i+1], i) .....: In [194]: np.fill_diagonal(a, 0) In [195]: a Out[195]: array([[ 0. , 1.3 , 0.56, -0.65], [ 43. , 0. , 0.54, 0.45], [ 7. , 0.5 , 0. , 0.12], [ 0.4 , 0.3 , 0.2 , 0. ]]) 
+2
source

Source: https://habr.com/ru/post/1214483/


All Articles