#python #arrays #sorting
Вопрос:
Я здесь новичок, я хочу поделиться с вами проблемой, с которой я сталкиваюсь
В основном я должен перенумеровать массив в соответствии с элементами другого массива.
Подробнее:
У меня есть массив int a
a=array([ 1, 2, 3, ..., 21041, 21042, 21043])
с
len(a)=21043
Затем, применяя маску к «a», он получает b
b=a[mask]
b=array[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 28 32 33 34 47 54 55 62....21043]
с
len(b)=15717
На данный момент я легко отсортировал этот массив таким образом:
b_renumber=array[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23....15717]
Таким образом, число 28 в «b» становится 21 в «b_renumber», 32 становится 22 и так далее.
Теперь проблема в третьем массиве c
так как c имеет длину больше, чем b.
len(c)=46153
и дается:
c=array[ 3 4 142 633 12 19 564 497 513 54 308 177 254 532 155 3 273 28 ...21037]
Таким образом, в основном c представляет собой массив длиной 46153 (несортированный) с элементами, которые идут от 1 до 21043, а также массив b, и, как и b, некоторые числа не существуют (например, 21 22 23 …и т. Д.), Т. Е. те же элементы, которые не существуют в b, также в c отсутствуют.
Что я хочу сделать, так это перенумеровать элементы c таким образом, чтобы существовала связь между значением элементов c и номером b_renumber. Пример в b у нас есть число 28, которое в b_renumber становится 21 (от b до b_renumber, 28 -> 21), и я хочу сделать следующее: каждый раз, когда я встречаю значение 28 в c, оно должно становиться 21, то же самое для других чисел.
И последнее: массив все еще невелик, но мне приходится работать с массивом большего размера, поэтому я должен делать это эффективно, возможно, существует функция или какой-то пакет, который позволяет мне это делать. Пожалуйста, я открыт для любых советов
Извините за длину поста, я надеюсь, что кто-то может и хочет мне помочь.
Заранее спасибо.
Маттео
Ответ №1:
Предполагая, что b_renum просто содержит индекс 1 каждого элемента в b:
Ввод:
b = [0,1,2,100]
c = [20,50,60,100]
Обратите внимание, что dict.get(key, default)
возвращает значение ключа, если есть совпадение, или значение по умолчанию в противном случае.
b_renum = list(range(1,len(b) 1))
renum_dict = dict(zip(b, b_renum))
# slightly slower
# renum_dict = {elem:ind for ind,elem in enumerate(b)}
c_renum = [renum_dict.get(key,key) for key in c]
>>> print(b_renum)
[1, 2, 3, 4]
>>> print(c_renum)
[20, 50, 60, 3]
Обратите внимание, как 100 сопоставляется с 3 дюймами c_renum
. Я думаю, что полезные вещи для вас: 1) использование zip()
, поскольку вы знаете b
, и b_renum
одинаковой длины, и 2) использование словаря для поиска значений dict.get()
трюк. Понимание списка также происходит довольно быстро.
Комментарии:
1. Большое спасибо. Только одно: мне не нужно сортировать c_renum, и после этого, чтобы хорошо перенумеровать, вам нужно добавить 1 к каждому элементу c_renum. Я имею в виду,что после c_renum = [renum_dict.get(ключ, ключ) для ключа в c], c_renum=np.массив(c_renum).astype(int) 1! Однако большое вам спасибо!
2. Если вам нужно добавить к каждому значению в списке, просто сделайте
c_renum = [renum_dict.get(key,key) 1 for key in c]
это . Или, может быть, вы все равно сможете найти более быстрое решение numpy.3. да, но, тем не менее, я должен преобразовать в массив после. В любом случае, я читаю ваше объяснение очень интересно! Я должен научиться пользоваться!
4. См. раздел Редактирование, есть более быстрый способ создания словаря