Numpy.argsort - can't see what's wrong

2020-03-08 05:50发布

问题:

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.  ]]

回答1:

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.



回答2:

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])