ПЕРЕНУМЕРОВАТЬ ЭЛЕМЕНТЫ МАССИВА 1D

#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. См. раздел Редактирование, есть более быстрый способ создания словаря