5

I am trying to sort a numpy array using the argsort function.

Unfortunately this is not working and I can't see why :(

The code is:

import numpy as np

distance = np.array([38.26,  33.01,  32.33,  30.77,  37.96,  44.37,  32.72,  36.56,
        27.77,  33.62,  42.85,  34.6 ,  32.04,  27.49,  49.64,  51.85,
        44.37,  38.26,  46.93,  40.45,  40.72,  39.7 ,  34.12,  36.9 ,
        34.6 ,  34.  ,  36.56,  39.29,  38.6 ,  32.33,  32.65,  40.72,
        43.85,  47.89,  33.62,  35.24,  42.5 ,  36.97,  28.36,  37.57,
        37.25,  25.54,  29.6 ,  37.25,  40.45,  32.04,  40.45,  31.4 ,
        41.78,  35.89,  59.24,  51.2 ,  57.22,  35.54,  50.09,  40.33,
        50.58,  29.77,  51.97,  34.33,  29.  ,  43.81,  40.84,  45.62,
        39.77,  54.5 ,  40.36,  40.93,  43.28,  37.61,  45.05,  45.05,
        45.94,  45.05,  49.37,  52.56,  54.08,  53.89,  44.41,  39.25,
        36.01,  36.01,  40.93,  43.29,  38.16,  47.56,  54.5 ,  44.98,
        40.36,  36.5 ,  37.01,  46.21,  40.4 ,  30.29,  38.65,  41.49,
        40.9 ,  46.85,  32.26,  40.33,  50.58,  40.93,  59.41,  48.1 ,
        51.25,  66.76,  30.26,  61.7 ,  51.14,  64.8 ,  52.49,  48.25,
        55.24,  38.74,  41.48,  51.2 ,  51.25,  73.73,  66.05,  40.84,
        57.85,  39.2 ,  67.13,  46.98,  55.78,  62.08,  46.28,  46.21,
        48.8 ,  60.84,  62.6 ,  76.85,  48.8 ,  47.53,  43.97,  68.29,
        51.25,  50.57,  45.  ,  57.22,  54.5 ,  57.22,  40.93,  56.48,
        55.78,  53.89,  45.94,  51.25,  50.  ,  43.81])

To debug it, I am printing the distance array together with the argsort:

print np.array(zip(distance, distance.argsort()))

What I get is this. It looks wrong, because for example 30.77 is smaller than 32.33, but 32.33 is marked as 8 and 30.77 as 38. What am I doing wrong?

[[  38.26   41.  ]
 [  33.01   13.  ]
 [  32.33    8.  ]
 [  30.77   38.  ]
 [  37.96   60.  ]
 [  44.37   42.  ]
 [  32.72   57.  ]
 [  36.56  106.  ]
 [  27.77   93.  ]
 [  33.62    3.  ]
 [  42.85   47.  ]
 [  34.6    45.  ]
 [  32.04   12.  ]
 [  27.49   98.  ]
 [  49.64    2.  ]
 [  51.85   29.  ]
 [  44.37   30.  ]
 [  38.26    6.  ]
 [  46.93    1.  ]
 [  40.45    9.  ]
 [  40.72   34.  ]
 [  39.7    25.  ]
 [  34.12   22.  ]
 [  36.9    59.  ]
 [  34.6    24.  ]
 [  34.     11.  ]
 [  36.56   35.  ]
 [  39.29   53.  ]
 [  38.6    49.  ]
 [  32.33   80.  ]
 [  32.65   81.  ]
 [  40.72   89.  ]
 [  43.85   26.  ]
 [  47.89    7.  ]
 [  33.62   23.  ]
 [  35.24   37.  ]
 [  42.5    90.  ]
 [  36.97   43.  ]
 [  28.36   40.  ]
 [  37.57   39.  ]
 [  37.25   69.  ]
 [  25.54    4.  ]
 [  29.6    84.  ]
 [  37.25    0.  ]
 [  40.45   17.  ]
 [  32.04   28.  ]
 [  40.45   94.  ]
 [  31.4   113.  ]
 [  41.78  121.  ]
 [  35.89   79.  ]
 [  59.24   27.  ]
 [  51.2    21.  ]
 [  57.22   64.  ]
 [  35.54   99.  ]
 [  50.09   55.  ]
 [  40.33   88.  ]
 [  50.58   66.  ]
 [  29.77   92.  ]
 [  51.97   46.  ]
 [  34.33   44.  ]
 [  29.     19.  ]
 [  43.81   20.  ]
 [  40.84   31.  ]
 [  45.62   62.  ]
 [  39.77  119.  ]
 [  54.5    96.  ]
 [  40.36   67.  ]
 [  40.93  101.  ]
 [  43.28  142.  ]
 [  37.61   82.  ]
 [  45.05  114.  ]
 [  45.05   95.  ]
 [  45.94   48.  ]
 [  45.05   36.  ]
 [  49.37   10.  ]
 [  52.56   68.  ]
 [  54.08   83.  ]
 [  53.89  149.  ]
 [  44.41   61.  ]
 [  39.25   32.  ]
 [  36.01  134.  ]
 [  36.01    5.  ]
 [  40.93   16.  ]
 [  43.29   78.  ]
 [  38.16   87.  ]
 [  47.56  138.  ]
 [  54.5    73.  ]
 [  44.98   71.  ]
 [  40.36   70.  ]
 [  36.5    63.  ]
 [  37.01  146.  ]
 [  46.21   72.  ]
 [  40.4   127.  ]
 [  30.29   91.  ]
 [  38.65  126.  ]
 [  41.49   97.  ]
 [  40.9    18.  ]
 [  46.85  123.  ]
 [  32.26  133.  ]
 [  40.33   85.  ]
 [  50.58   33.  ]
 [  40.93  103.  ]
 [  59.41  111.  ]
 [  48.1   132.  ]
 [  51.25  128.  ]
 [  66.76   74.  ]
 [  30.26   14.  ]
 [  61.7   148.  ]
 [  51.14   54.  ]
 [  64.8   137.  ]
 [  52.49  100.  ]
 [  48.25   56.  ]
 [  55.24  108.  ]
 [  38.74  115.  ]
 [  41.48   51.  ]
 [  51.2   104.  ]
 [  51.25  136.  ]
 [  73.73  116.  ]
 [  66.05  147.  ]
 [  40.84   15.  ]
 [  57.85   58.  ]
 [  39.2   110.  ]
 [  67.13   75.  ]
 [  46.98  145.  ]
 [  55.78   77.  ]
 [  62.08   76.  ]
 [  46.28   65.  ]
 [  46.21  140.  ]
 [  48.8    86.  ]
 [  60.84  112.  ]
 [  62.6   144.  ]
 [  76.85  124.  ]
 [  48.8   143.  ]
 [  47.53  139.  ]
 [  43.97  141.  ]
 [  68.29   52.  ]
 [  51.25  120.  ]
 [  50.57   50.  ]
 [  45.    102.  ]
 [  57.22  129.  ]
 [  54.5   107.  ]
 [  57.22  125.  ]
 [  40.93  130.  ]
 [  56.48  109.  ]
 [  55.78  118.  ]
 [  53.89  105.  ]
 [  45.94  122.  ]
 [  51.25  135.  ]
 [  50.    117.  ]
 [  43.81  131.  ]]
  • This is a very related question https://stackoverflow.com/questions/17901218/numpy-argsort-what-is-it-doing – Schach21 Aug 09 '21 at 15:47

2 Answers2

16

distance.argsort() returns an array of indices. The ith index does not tell you the rank of the ith element in distance. Rather, the ith index tells you that the ith element in the sorted array is distance[i].

In other words,

idx = distance.argsort()
assert (distance[idx] == np.sort(distance)).all()

Consider this small example from the docs:

In [236]: x = np.array([3, 1, 2])

In [237]: np.argsort(x)
Out[237]: array([1, 2, 0])

In [238]: x[np.argsort(x)]
Out[238]: array([1, 2, 3])

In [239]: x[1], x[2], x[0]
Out[239]: (1, 2, 3)

Calling argsort twice does gives you the rank of the ith element in distance:

In [240]: np.argsort(np.argsort(x))
Out[240]: array([2, 0, 1])

Understanding how this works is a good test of your understanding of argsort. However, calling argsort twice to find the rank is inefficient. Especially for larger arrays there are other, faster, ways to find the rank.

Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
-1

The following works for me:

distance.sort()

which returns

array([ 25.54,  27.49,  27.77,  28.36,  29.  ,  29.6 ,  29.77,  30.26,
        30.29,  30.77,  31.4 ,  32.04,  32.04,  32.26,  32.33,  32.33,
        32.65,  32.72,  33.01,  33.62,  33.62,  34.  ,  34.12,  34.33,
        34.6 ,  34.6 ,  35.24,  35.54,  35.89,  36.01,  36.01,  36.5 ,
        36.56,  36.56,  36.9 ,  36.97,  37.01,  37.25,  37.25,  37.57,
        37.61,  37.96,  38.16,  38.26,  38.26,  38.6 ,  38.65,  38.74,
        39.2 ,  39.25,  39.29,  39.7 ,  39.77,  40.33,  40.33,  40.36,
        40.36,  40.4 ,  40.45,  40.45,  40.45,  40.72,  40.72,  40.84,
        40.84,  40.9 ,  40.93,  40.93,  40.93,  40.93,  41.48,  41.49,
        41.78,  42.5 ,  42.85,  43.28,  43.29,  43.81,  43.81,  43.85,
        43.97,  44.37,  44.37,  44.41,  44.98,  45.  ,  45.05,  45.05,
        45.05,  45.62,  45.94,  45.94,  46.21,  46.21,  46.28,  46.85,
        46.93,  46.98,  47.53,  47.56,  47.89,  48.1 ,  48.25,  48.8 ,
        48.8 ,  49.37,  49.64,  50.  ,  50.09,  50.57,  50.58,  50.58,
        51.14,  51.2 ,  51.2 ,  51.25,  51.25,  51.25,  51.25,  51.85,
        51.97,  52.49,  52.56,  53.89,  53.89,  54.08,  54.5 ,  54.5 ,
        54.5 ,  55.24,  55.78,  55.78,  56.48,  57.22,  57.22,  57.22,
        57.85,  59.24,  59.41,  60.84,  61.7 ,  62.08,  62.6 ,  64.8 ,
        66.05,  66.76,  67.13,  68.29,  73.73,  76.85])
wigging
  • 8,492
  • 12
  • 75
  • 117