NumPy: Unsort/undo a reverse/descending sort
The following idiom is cheaper (O(n)) than the second argsort (O(n log n)).
Example array x
with sort order y
>>> x = np.random.random(10)
>>> y = x.argsort()[::-1]
Build inverse i
>>> i = np.empty_like(y)
>>> i[y] = np.arange(y.size)
Check:
>>> x
array([0.44257134, 0.573158 , 0.07762422, 0.31507426, 0.43414726,
0.34923861, 0.22161337, 0.14090133, 0.66903264, 0.38888105])
>>> x[y]
array([0.66903264, 0.573158 , 0.44257134, 0.43414726, 0.38888105,
0.34923861, 0.31507426, 0.22161337, 0.14090133, 0.07762422])
>>> x[y][i]
array([0.44257134, 0.573158 , 0.07762422, 0.31507426, 0.43414726,
0.34923861, 0.22161337, 0.14090133, 0.66903264, 0.38888105])
Given the unsorted example:
a = np.array([-1, -2, 1, -3, 2, 0])
To unsort/undo its reverse/descending sort:
i = a.argsort()[::-1]
# i = array([4, 2, 5, 0, 1, 3])
a = a[i] # descending sort using i
# a = array([ 2, 1, 0, -1, -2, -3])
a = a[i.argsort()] # unsort using i
# a = array([-1, -2, 1, -3, 2, 0])
Credit: This answer is motivated by one on how to unsort a sort which doesn't concern with reverse sort.