undo or reverse argsort(), python
There are probably better solutions to the problem you are actually trying to solve than this (performing an argsort usually precludes the need to actually sort), but here you go:
>>> import numpy as np>>> a = np.random.randint(0,10,10)>>> aa = np.argsort(a)>>> aaa = np.argsort(aa)>>> a # originalarray([6, 4, 4, 6, 2, 5, 4, 0, 7, 4])>>> a[aa] # sortedarray([0, 2, 4, 4, 4, 4, 5, 6, 6, 7])>>> a[aa][aaa] # undonearray([6, 4, 4, 6, 2, 5, 4, 0, 7, 4])
I'm not sure how best to do it in numpy
, but, in pure Python, the reasoning would be:
aargsort
is holding a permutation of range(len(a))
telling you where the items of aSort
came from -- much like, in pure Python:
>>> x = list('ciaobelu')>>> r = range(len(x))>>> r.sort(key=x.__getitem__)>>> r[2, 4, 0, 5, 1, 6, 3, 7]>>>
i.e., the first argument of sorted(x)
will be x[2]
, the second one x[4]
, and so forth.
So given the sorted version, you can reconstruct the original by "putting items back where they came from":
>>> s = sorted(x)>>> s['a', 'b', 'c', 'e', 'i', 'l', 'o', 'u']>>> original = [None] * len(s)>>> for i, c in zip(r, s): original[i] = c... >>> original['c', 'i', 'a', 'o', 'b', 'e', 'l', 'u']>>>
Of course there are going to be tighter and faster ways to express this in numpy
(which unfortunately I don't know inside-out as much as I know Python itself;-), but I hope this helps by showing the underlying logic of the "putting things back in place" operation you need to perform.