The argsort function seems to be broken. Looking at the code provided, the argsort for rows [0, 1] is correct but it's messed up for rows [2, 3].
I tested this on different NumPy installations and versions 1.11.0 and 1.12.0
import numpy as np
vec = np.array([
[-1.4, -1.2, 1.3],
[-3.6, 3.9, -3.7],
[-2.3, 1.5, -2. ],
[-2.6, 2.4, -1.6]
])
In [1]: np.argsort(-vec, axis=1)
Out[1]:
array([[2, 1, 0],
[1, 0, 2],
[1, 2, 0],
[1, 2, 0]])
Can't see anything wrong with the result, print out vec[np.arange(4)[:, np.newaxis], np.argsort(-vec, axis=1)]
and see that it looks good.
This is the second google result for "np argsort wrong".
The explanation on the docs page is unclear (to me). I will add my own explanation here in the hopes that it helps someone:
x = numpy.array([1.48,1.31,0.0,0.8])
print x.argsort()
>[2 3 1 0]
Some people might expect this to instead give [3, 2, 0, 1]
, i.e., the 0th element in the unsorted array should be the 3rd element in the sorted array.
What it actually does is provide indices such that x[np.argsort(x)]
will give you a sorted list, i.e., [0.0, 0.8, 1.31, 1.48]
. Put another way, [2 3 1 0]
tells you that the 0th element of the sorted array is the 2nd element of the unsorted array.
If you really want to get [3, 2, 0, 1]
as an output, you can instead do
np.argsort(np.argsort(x))
>[3 2 0 1]
Alternatively, if you're just really off-base like I was and only want, say, the indices of the 3 largest elements in x
:
np.argsort(x)[:-4:-1]
>[0, 1, 3]
If you really want to get [3, 2, 0, 1] as an output, you can instead do
Doing this will be faster:
a = np.empty(len(x), np.intp)
a[np.argsort(x)] = np.arange(len(x))
np.invert_permutation(np.argsort(x))
@rossbar, @bjnath: Perhaps worth extracting stuff from @ghost's comment above and putting it in the docs? I've added some more crosslinks to show more examples of confusion.
Most helpful comment
This is the second google result for "np argsort wrong".
The explanation on the docs page is unclear (to me). I will add my own explanation here in the hopes that it helps someone:
Some people might expect this to instead give
[3, 2, 0, 1]
, i.e., the 0th element in the unsorted array should be the 3rd element in the sorted array.What it actually does is provide indices such that
x[np.argsort(x)]
will give you a sorted list, i.e.,[0.0, 0.8, 1.31, 1.48]
. Put another way,[2 3 1 0]
tells you that the 0th element of the sorted array is the 2nd element of the unsorted array.If you really want to get
[3, 2, 0, 1]
as an output, you can instead doAlternatively, if you're just really off-base like I was and only want, say, the indices of the 3 largest elements in
x
: