[Numpy-discussion] Strange behavior for argsort() and take()

Anne Archibald peridot.faceted@gmail....
Wed Jun 18 10:10:01 CDT 2008


2008/6/18 Thomas J. Duck <tom.duck@dal.ca>:

>      I have found what I think is some strange behavior for argsort
> () and take().  First, here is an example that works as expected:
>
>      >>> x = numpy.array([1,0,3,2])
>      >>> x.argsort()
>      array([1, 0, 3, 2])
>
> argsort() returns the original array, which is self-indexing for
> numbers 0 through 3...
>
>      >>> x.take(x.argsort())
>      array([0, 1, 2, 3])
>
> ...and take() provides the correct sort with ascending order.
>
> Now check out what happens when we swap the middle two numbers:
>
>      >>> x = numpy.array([1,3,0,2])
>      >>> x.argsort()
>      array([2, 0, 3, 1])
>
> argsort() appears to have indexed the numbers in descending order
> (which was not expected)....
>
>      >>> x.take(x.argsort())
>      array([0, 1, 2, 3])
>
> ... but the take() operation puts them in ascending order anyway
> (which was really not expected)!
>
>      Can anyone shed some light on what is happening here for me?  I
> have tested this on both my OS X/Fink and Debian/Lenny systems with
> the same result.

This is the intended behaviour. The array returned by np.argsort() is
designed to be used as an index into the original array (take() does
almost the same thing as indexing). In particular, when x.argsort()
returns array([2,0,3,1]), that means that the sorted array is x[2],
x[0], x[3], x[1]. It might be clearer to sort a different array:

In [3]: x = np.array([0.1,0.3,0.0,0.2])

In [5]: x.argsort()
Out[5]: array([2, 0, 3, 1])

In [7]: x.take(x.argsort())
Out[7]: array([ 0. ,  0.1,  0.2,  0.3])

If you would like to think of it more mathematically, when you feed
np.argsort() an array that represents a permutation of the numbers
0,1,...,n-1, you get back the inverse permutation. When you pass a
permutation as the argument to x.take(), you apply the permutation to
x. (You can also invert a permutation by feeding it as indices to
arange(n)).

I have been tempted to write some support functions for manipulating
permutations, but I'm not sure how generally useful they would be.

Anne


More information about the Numpy-discussion mailing list