Search code examples
pythonalgorithmnumpyvectorization

How to invert a permutation array in numpy


Given a self-indexing (not sure if this is the correct term) numpy array, for example:

a = np.array([3, 2, 0, 1])

This represents this permutation (=> is an arrow):

0 => 3
1 => 2
2 => 0
3 => 1

I'm trying to make an array representing the inverse transformation without doing it "manually" in python, that is, I want a pure numpy solution. The result I want in the above case is:

array([2, 3, 1, 0])

Which is equivalent to

0 <= 3                0 => 2
1 <= 2       or       1 => 3
2 <= 0                2 => 1
3 <= 1                3 => 0

It seems so simple, but I just can't think of how to do it. I've tried googling, but haven't found anything relevant.


Solution

  • The inverse of a permutation p of np.arange(n) is the array of indices s that sort p, i.e.

    p[s] == np.arange(n)
    

    must be all true. Such an s is exactly what np.argsort returns:

    >>> p = np.array([3, 2, 0, 1])
    >>> np.argsort(p)
    array([2, 3, 1, 0])
    >>> p[np.argsort(p)]
    array([0, 1, 2, 3])