I have a numpy array in Python which is n-by-n (in the example is 3-by-3)and contains zero values in all the diagonal positions. e.g
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 the array without modifying the diagonal positions so as to look like the one below? Because all of the sorting functions will take into account the "zeros" that exist in the diagonal positions and will 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 done, then the N maximum values and their corresponding indexes in each row could suffice.
Till now i have tried sort and argsort but with no result.
I'm a little late to this question, but if you're looking for a NumPy-only solution, you could substitute inf
for your diagonal, sort in your chosen 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. ]])
The easiest approach is to remove the zeroes, sort, then add the zeroes back along the diagonal:
>>> 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]]
Wrapped into a 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]]
>>>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With