question

given a list of numbers, return the order index of each element;

for example, if input is:

input = [ 6, 4, 9, 3 ]

we should return:

output = [ 2, 1, 3, 0 ]

answer

there is an elegant solution with numpy.argsort:

output = numpy.argsort(numpy.argsort(input))

to understand how it works, first of all, we know argsort returns indices that would sort an array; that means, argsort acts as if it first sorts elements by their values, then label elements by their original indices;

to visualize what is happening, we can label the elements with their indices, turning them into tuples:

      label     argsort     label       argsort
6 4 9 3 => 6 4 9 3 => 3 4 6 9    3 4 6 9    6 4 9 3
        -> 0 1 2 3    3 1 0 2 => 3 1 0 2 => 0 1 2 3
                              -> 0 1 2 3    2 1 3 0

note that the 2nd argsort places elements into their original order, but keeps their indices in the sorted list: those are the order indices; now this explains how this solution works;

finally, argsort has an interesting property: repeatedly doing argsort will ping-pong between two lists; in the above example, they are:

3 1 0 2 <=> 2 1 3 0