Сортируйте один список, чтобы два списка имели правильное соответствие порядку - PullRequest
0 голосов
/ 14 сентября 2018

У меня есть два списка, например,

coords = [2, 0, 1, 4, 3]
value = [1, 9, 3, 3, 0]

, где первая представляет собой серию координат, а вторая представляет собой последовательность значений, соответствующих координатам, например, координата '2' соответствует значению '1', координаты '0' дают значение '9'.

Теперь я бы хотел отсортировать coords , но оставить порядок value без изменений, чтобы наименьший элемент coords соответствовал наименьшему элементу в value и т. Д. , Желаемый результат будет:

coords_new = [1, 4, 2, 3, 0]
value = [1, 9, 3, 3, 0] # unchanged

, где '0' -> '0', '1' -> '1', '2' -> '3', '3' -> '3', '4' -> '9'. Есть идеи, чтобы сделать это? Вы можете вернуть coords_new или индексы, которые переупорядочивают coords в качестве ответа.

Edit: Если возможно, я предпочитаю, чтобы мы возвращали индексы, которые изменяют порядок оригинала coords, то есть возвращают idx так, чтобы coords[idx] = coords_new.

Большое спасибо!

Zhihao

Ответы [ 3 ]

0 голосов
/ 14 сентября 2018

Я предполагаю, что вы хотите получить пустой ответ, поскольку вы пометили numpy:

>>> x = np.argsort(value)
>>> x[x]
array([1, 4, 2, 3, 0])
0 голосов
/ 15 сентября 2018

Вот полтора решения с использованием argsort.Аргумент kind='mergesort' kwd необходим, только если вам требуется стабильная сортировка.В вашем примере нестабильная сортировка может также дать coords_new == [1, 4, 3, 2, 0].Если это не проблема, вы можете опустить kwd arg и позволить numpy использовать более быстрый алгоритм сортировки.

import numpy as np

coords = [2, 0, 1, 4, 3]
value = [1, 9, 3, 3, 0]

coords, value = map(np.asanyarray, (coords, value))

vidx = value.argsort(kind='mergesort') # mergesort is stable, i.e. it  
                                       # preserves the order of equal elements

# direct method:
coords_new = np.empty_like(coords)
coords_new[vidx] = np.sort(coords)

# method yielding idx
idx = np.empty_like(vidx)
idx[vidx] = coords.argsort(kind='mergesort') 

Второй метод выдает idx, такой что coords_new == coords[idx].

0 голосов
/ 14 сентября 2018

Один из вариантов - сначала создать отображение между объектами, а затем использовать это отображение в сочетании с индексом:

coords = [2, 0, 1, 4, 3]
value = [1, 9, 3, 3, 0]

table = {k: v for k, v in zip(sorted(coords), sorted(value))}
print(table)
print(sorted(coords, key=lambda e: value.index(table[e])))

Выход

{0: 0, 1: 1, 2: 3, 3: 3, 4: 9}
[1, 4, 2, 3, 0]

Примечание

Этот метод предполагает, что coords содержит только уникальные значения.В общем случае вы можете сгенерировать пары (c, v) сопоставления для сортировки по значению индекса v в значении:

pairs = [(k, v) for k, v in zip(sorted(coords), sorted(value))]
result = [k for k, _ in sorted(pairs, key=lambda e: value.index(e[1]))]

print(result)

Выход

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