быстро сортировать очень длинный список целых чисел в python - PullRequest
0 голосов
/ 15 мая 2019

У меня есть вектор из нескольких сотен миллионов элементов np.uint8.Их значение варьируется от 0 до 255.

Мне нужно отсортировать этот список, и я думаю, что он должен обрабатываться быстрее, чем быстрая сортировка.Я думаю, что я мог бы найти индексы для всех значений "0" и поместить их впереди, затем для всех значений "1" и поместить их после последней вставки, и прогрессировать, пока я не закончу.Это будет мутантное потомство уникального и сортированного с некоторым индексированием и должно работать очень быстро.

Есть ли встроенный модуль, который делает это хорошо, правильно и в чем-то быстром, как «C», без необходимостидоморощенный это?Не могли бы вы указать мне на это?

Скажем, в качестве "игрушки" моей настоящей проблемы я хотел отсортировать значения интенсивности для каждого цвета (rgb) 100-мегапиксельной версии мандрилаimage где каждый цвет был преобразован в один очень длинный вектор значений uint8.Если бы у меня была разница во времени между методами сортировки, которые было бы разумно вычислить, в python?

Ответы [ 3 ]

2 голосов
/ 15 мая 2019

Вы можете обнаружить, что 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])

То есть 0 встречается 0 раз в r, 13 встречается 3 раза и т. Д .:

In [105]: b[0], b[13]                                                                                                                                                                                  
Out[105]: (0, 3)
1 голос
/ 15 мая 2019

Вы можете сделать это без сортировки с помощью 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)
0 голосов
/ 15 мая 2019

Если вам нужны только отсортированные значения , тогда bincount - действительно путь.Если, однако, то, что вам требуется, больше похоже на argsort, например, вам нужно совместно отсортировать какой-либо другой массив той же длины, то вы можете использовать this Q & A . Он сравнивает различные методы, некоторые из которых намного быстреечем «наивный» argsort.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...