3

I'm new to numpy, so I might be missing something obviuous here.

The following small argsort() test script gives strange results. Any directions ?

import numpy as np

a = np.array([[3, 5, 6, 4, 1] , [2, 7 ,4 ,1 , 2] , [8, 6, 7, 2, 1]])
print a
print a.argsort(axis=0)
print a.argsort(axis=1)

output:

[[3 5 6 4 1]
 [2 7 4 1 2]
 [8 6 7 2 1]]
[[1 0 1 1 0]   # bad 4th & 5th columns ?
 [0 2 0 2 2]
 [2 1 2 0 1]]
[[4 0 3 1 2]   # what's going on here ?
 [3 0 4 2 1]
 [4 3 1 2 0]]
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
eyalasko
  • 75
  • 6
  • 1
    How are those `"bad 4th & 5th columns"`? – Divakar May 31 '17 at 13:23
  • 1
    @eyalasko the results are correct – Saullo G. P. Castro May 31 '17 at 13:33
  • 1
    Put other way - Whatelse were you expecting and why? – Divakar May 31 '17 at 13:33
  • @Divakar, maybe I'm missing something but shouldn't column 4 be: [2 0 1].transpose (as its related to [[4 1 2]] column vector) ? – eyalasko May 31 '17 at 13:36
  • and row 1 : [[1 3 4 2 0]] ? – eyalasko May 31 '17 at 13:38
  • 1
    As docs on `np.argsort` state : `"Returns the indices that would sort an array."`. So, `argsort` gives us the indices which when indexed into the input would give us the sorted version. – Divakar May 31 '17 at 13:40
  • 2
    Since the numpy.argsort() function is obviously corrent and working for several years now, the problem is more the interpretation. Now it seems that you interprete the result differently and thus think it's wrong. However in order to help you here, we would need to know what you would expect (please put your comments into the question!) and **why** you would expect that. – ImportanceOfBeingErnest May 31 '17 at 13:42
  • Thanks Divakar. @ImportanceOfBeingErnest I mistakenly thought that the returned value is the _order_ of the element ... – eyalasko May 31 '17 at 13:51
  • If you wanted to [rank](https://en.wikipedia.org/wiki/Ranking) the data, take a look at https://stackoverflow.com/questions/5284646/rank-items-in-an-array-using-python-numpy – Warren Weckesser May 31 '17 at 14:20

2 Answers2

2

As others have indicated this method is working correctly, so in order to provide an answer here is an explanation of how .argsort() works. a.argsort returns the indices (not values) in order that would sort the array along the specified axis.

In your example

a = np.array([[3, 5, 6, 4, 1] , [2, 7 ,4 ,1 , 2] , [8, 6, 7, 2, 1]])
print a
print a.argsort(axis=0)

returns

[[3 5 6 4 1]
 [2 7 4 1 2]
 [8 6 7 2 1]]
[[1 0 1 1 0]
 [0 2 0 2 2]
 [2 1 2 0 1]]

because along

[[3 ...
[2 ...
[8 ...

2 is the smallest value. Therefore the current index of 2 (which is 0) takes the first position along this axis in the matrix returned by argsort(). The second smallest value is 3 at index 0, therefore the second position along this axis in the returned matrix will be 0. Finally, the largest element is 2 which occurs at index 2 along the 0 axis, so the final element of the returned matrix will be 2. Thus:

[[1 ...
[0 ...
[2 ...

the same process is repeated along other 4 sequences along axis 0:

 [[...5 ...]                     [[...0 ...]
 [...7 ...]    becomes ---->     [... 2 ...]
 [...6 ...]]                     [... 1 ...]]

 [[...6 ...]                     [[...1 ...]
 [...4 ...]    becomes ---->     [... 0 ...]
 [...7 ...]]                     [... 2 ...]]

 [[...4 ...]                     [[...1 ...]
 [...1 ...]    becomes ---->     [... 2 ...]
 [...2 ...]]                     [... 0 ...]]

 [[...1]                     [[...0]
 [...2]    becomes ---->     [... 2]
 [...1]]                     [... 1]]

changing the axis to from 0 to 1, results in this same process being applied along sequences in the 1st axis:

[[3 5 6 4 1  becomes ----> [[4 0 3 1 2

again because the smallest element is 1 which is at index 4, then 3 at index 0, then 4 at index 3, 5 at index 1 and finally 6 is the largest at index 2.

As before this process is repeated across each of

[2 7 4 1 2]     ---->   [3 0 4 2 1]
[8 6 7 2 1]     ---->   [4 3 1 2 0]

giving

[[4 0 3 1 2]  
[3 0 4 2 1]
[4 3 1 2 0]]
FinleyGibson
  • 911
  • 5
  • 18
-1

This actually returns a sorted array, whose elements, rather than the element of the array we want to sort, are the index of that element.

enter image description here

enter image description here

This says the first element in our sorted array would be the element whose index is '1', which in turn is '0'.

  • Please don't post images of code or results: take the time to copy your finding in the answer itself. – rikyeah Feb 07 '22 at 13:56