在python中快速排序很长的整数列表

时间:2019-05-15 16:27:21

标签: python numpy sorting int

我有一个包含np.uint8的几亿个元素的向量。它们的值范围从0到255。

我需要对该列表进行排序,并且我认为应该比快速排序更快地处理它。我想我可以找到所有值“ 0”的索引,并将它们放在最前面,然后为所有值“ 1”,将它们放在最后一个插入之后,然后进行直到完成。这将是唯一且具有一定索引的排序的突变后代,并且应该很快起作用。

是否有一个内置的程序可以很好地,正常地并且以“ C”之类的速度快速运行,而无需我进行自制程序?你能指出我吗?

让我们说,作为我实际问题的“玩具”,我想对mandrill image的100兆像素版本的每种颜色(rgb)的强度值进行排序,其中每种颜色已转换为单一颜色,非常长,是uint8值的向量。如果我要用python排序的方法之间的差异(可以合理地计算)的时间?

3 个答案:

答案 0 :(得分:2)

您可能会发现numpy.bincount就是您所需要的。它计算数据中每个整数的出现次数。

例如,这是一些随机的无符号8位整数:

In [100]: np.random.seed(8675309)                                                                                                                                                                      

In [101]: r = np.random.gamma(9, scale=8.5, size=100000).astype(np.uint8)                                                                                                                              

In [102]: r.min(), r.max()                                                                                                                                                                             
Out[102]: (11, 242)

使用bincount计算整数:

In [103]: b = np.bincount(r, minlength=256)                                                                                                                                                            

In [104]: b                                                                                                                                                                                            
Out[104]: 
array([   0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
          1,    1,    3,    1,    5,   13,    9,   17,   24,   31,   27,
         41,   55,   63,   96,  131,  146,  178,  210,  204,  268,  297,
        308,  367,  422,  480,  512,  584,  635,  669,  671,  759,  830,
        885,  934,  955, 1025, 1105, 1146, 1145, 1344, 1271, 1353, 1300,
       1456, 1419, 1451, 1504, 1499, 1561, 1600, 1509, 1678, 1621, 1643,
       1633, 1616, 1574, 1677, 1664, 1682, 1625, 1608, 1581, 1598, 1575,
       1583, 1524, 1493, 1381, 1448, 1399, 1422, 1249, 1322, 1225, 1278,
       1174, 1246, 1128, 1161, 1077,  999, 1033,  980,  981,  897,  917,
        880,  813,  779,  774,  697,  716,  651,  612,  657,  592,  556,
        497,  482,  474,  484,  445,  411,  399,  354,  368,  363,  342,
        313,  301,  293,  263,  241,  249,  244,  196,  215,  182,  189,
        172,  161,  139,  143,  142,  120,  121,  104,  103,  112,   88,
         82,   88,   67,   60,   83,   57,   63,   59,   50,   52,   55,
         40,   34,   34,   43,   35,   33,   28,   24,   26,   20,   18,
         21,   26,   30,   17,   15,   12,   17,   11,    7,    6,   16,
          8,    3,    4,   12,    9,    6,    5,    8,   10,    7,    1,
          4,    8,    5,    3,    2,    1,    0,    1,    1,    0,    1,
          0,    0,    4,    2,    2,    0,    0,    2,    0,    1,    1,
          1,    4,    0,    0,    0,    0,    0,    0,    0,    0,    2,
          1,    0,    0,    0,    0,    0,    1,    0,    0,    0,    0,
          0,    0,    0,    1,    0,    0,    0,    0,    0,    0,    0,
          1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
          0,    0,    0])

因此r中0发生0次,13发生3次,依此类推:

In [105]: b[0], b[13]                                                                                                                                                                                  
Out[105]: (0, 3)

答案 1 :(得分:1)

您可以执行此操作而无需使用bincount进行排序并重复:

In [11]: a = np.bincount(np.array([71, 9, 1, 2, 3, 4, 4, 4, 8, 9, 9, 71], dtype=np.uint8), minlength=256)

In [12]: np.repeat(np.arange(256, dtype=np.uint8), a)
Out[12]: array([ 1,  2,  3,  4,  4,  4,  8,  9,  9,  9, 71, 71], dtype=uint8)

答案 2 :(得分:0)

如果只需要排序的,那么bincount确实是可行的方法。但是,如果您需要的参数更像argsort,例如,您需要对其他相同长度的数组进行共排序,则可以使用this Q&A来比较各种方法,其中有些方法比'天真” argsort