Сортировать многомерный список - Python - PullRequest
3 голосов
/ 19 марта 2020

У меня есть трехмерный список списков или массив numpy, и мне нужно отсортировать его по наименьшему индексу первого элемента. Это последние два предположения, которые я сделал по этой программе. Извините, я вполне уверен, что это простой / глупый вопрос, но как новичок ie в программировании «образ мышления», мне это довольно сложно. Первая попытка:

 lstsArray = [[[54,21,31], [1,2,3], [15,25,35]],
              [[12,22,32], [3,2,1], [16,26,36]],
              [[34,24,38], [0.1,1,1], [17,27,37]]]
 val = np.array(lstsArray)
 menor = 120e26
 for item in val:
     for i in item:
         if menor >= i[0] and i[0] >= min(i):
             menor = i[0]
 print(menor)
 lstA = list(val)
 a = sorted(lstA, key=itemgetter(menor))
 print(a)

Вторая попытка

for i in val:
    for j in i:
        print(sorted((i), key =itemgetter(j[0])))

Желаемый выход

[[[0.1,1,1],[1,2,3],[3,2,1]],
 [[12,22,32],[15,25,35],[16,26,36]],
 [[17,27,37],[34,24,38],[54,21,31]]] 

1 Ответ

0 голосов
/ 19 марта 2020

Ваш список и массив из него. Обратите внимание на числа с плавающей точкой в ​​массиве:

In [124]: lstsArray = [[[54,21,31], [1,2,3], [15,25,35]], 
     ...:               [[12,22,32], [3,2,1], [16,26,36]], 
     ...:               [[34,24,38], [0.1,1,1], [17,27,37]]]                                                         
In [125]: val=np.array(lstsArray)                                                                                    
In [126]: val                                                                                                        
Out[126]: 
array([[[54. , 21. , 31. ],
        [ 1. ,  2. ,  3. ],
        [15. , 25. , 35. ]],

       [[12. , 22. , 32. ],
        [ 3. ,  2. ,  1. ],
        [16. , 26. , 36. ]],

       [[34. , 24. , 38. ],
        [ 0.1,  1. ,  1. ],
        [17. , 27. , 37. ]]])

Это массив (3,3,3). Но ваша сортировка игнорирует начальный (3,3) макет, поэтому давайте go вперед и изменим его:

In [133]: val = np.array(lstsArray).reshape(-1,3)                                                                    
In [134]: val                                                                                                        
Out[134]: 
array([[54. , 21. , 31. ],
       [ 1. ,  2. ,  3. ],
       [15. , 25. , 35. ],
       [12. , 22. , 32. ],
       [ 3. ,  2. ,  1. ],
       [16. , 26. , 36. ],
       [34. , 24. , 38. ],
       [ 0.1,  1. ,  1. ],
       [17. , 27. , 37. ]])

Теперь мы можем легко изменить форму первого столбца. argsort дает порядок сортировки:

In [135]: idx = np.argsort(val[:,0])                                                                                 
In [136]: idx                                                                                                        
Out[136]: array([7, 1, 4, 3, 2, 5, 8, 6, 0])
In [137]: val[idx]                                                                                                   
Out[137]: 
array([[ 0.1,  1. ,  1. ],
       [ 1. ,  2. ,  3. ],
       [ 3. ,  2. ,  1. ],
       [12. , 22. , 32. ],
       [15. , 25. , 35. ],
       [16. , 26. , 36. ],
       [17. , 27. , 37. ],
       [34. , 24. , 38. ],
       [54. , 21. , 31. ]])

и возвращает его в 3d:

In [138]: val[idx].reshape(3,3,3)                                                                                    
Out[138]: 
array([[[ 0.1,  1. ,  1. ],
        [ 1. ,  2. ,  3. ],
        [ 3. ,  2. ,  1. ]],

       [[12. , 22. , 32. ],
        [15. , 25. , 35. ],
        [16. , 26. , 36. ]],

       [[17. , 27. , 37. ],
        [34. , 24. , 38. ],
        [54. , 21. , 31. ]]])

или в виде списка:

In [139]: val[idx].reshape(3,3,3).tolist()                                                                           
Out[139]: 
[[[0.1, 1.0, 1.0], [1.0, 2.0, 3.0], [3.0, 2.0, 1.0]],
 [[12.0, 22.0, 32.0], [15.0, 25.0, 35.0], [16.0, 26.0, 36.0]],
 [[17.0, 27.0, 37.0], [34.0, 24.0, 38.0], [54.0, 21.0, 31.0]]]

Но если список имел только один уровень вложенности:

In [140]: alist = val.tolist()                                                                                       
In [141]: alist                                                                                                      
Out[141]: 
[[54.0, 21.0, 31.0],
 [1.0, 2.0, 3.0],
 [15.0, 25.0, 35.0],
 [12.0, 22.0, 32.0],
 [3.0, 2.0, 1.0],
 [16.0, 26.0, 36.0],
 [34.0, 24.0, 38.0],
 [0.1, 1.0, 1.0],
 [17.0, 27.0, 37.0]]

сортировка python работает довольно хорошо:

In [142]: sorted(alist, key=lambda x:x[0])   # or itemgetter                                                                           
Out[142]: 
[[0.1, 1.0, 1.0],
 [1.0, 2.0, 3.0],
 [3.0, 2.0, 1.0],
 [12.0, 22.0, 32.0],
 [15.0, 25.0, 35.0],
 [16.0, 26.0, 36.0],
 [17.0, 27.0, 37.0],
 [34.0, 24.0, 38.0],
 [54.0, 21.0, 31.0]]

Тот факт, что у вас есть двойной вложенный список, но вы хотите отсортировать игнорировать один слой, усложняет обработку списка. Вот где numpy изменение формы очень помогает.

Пока я не буду тестировать относительные скорости этих подходов.

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