pythonarraysnumpysortingstable-sort

NumPy - descending stable arg-sort of arrays of any dtype


NumPy's np.argsort is able to do stable sorting through passing kind = 'stable' argument.

Also np.argsort doesn't support reverse (descending) order.

If non-stable behavior is needed then descending order can be easily modeled through desc_ix = np.argsort(a)[::-1].

I'm looking for efficient/easy solution to descending-stable-sort NumPy's array a of any comparable dtype. See my meaning of "stability" in the last paragraph.

For the case when dtype is any numerical then stable descending arg-sorting can be easily done through sorting negated version of array:

print(np.argsort(-np.array([1, 2, 2, 3, 3, 3]), kind = 'stable'))
# prints: array([3, 4, 5, 1, 2, 0], dtype=int64)

But I need to support any comparable dtype including np.str_ and np.object_.

Just for clarification - maybe for descending orders classical meaning of stable means that equal elements are enumerated right to left. If so then in my question meaning of stable + descending is something different - equal ranges of elements should be enumerated left to right, while equal ranges between each other are ordered in descending order. I.e. same behavior should be achieved like in the last code above. I.e. I want stability in a sense same like Python achieves in next code:

print([e[0] for e in sorted(enumerate([1,2,2,3,3,3]), key = lambda e: e[1], reverse = True)])
# prints: [3, 4, 5, 1, 2, 0]

Solution

  • I think this formula should work:

    import numpy as np
    a = np.array([1, 2, 2, 3, 3, 3])
    s = len(a) - 1 - np.argsort(a[::-1], kind='stable')[::-1]
    print(s)
    # [3 4 5 1 2 0]