2017-02-23 61 views
1

Скажем, у меня есть эти два массива:Как применить не целое число -> integer dict к массиву numpy?

dictionary = np.array(['a', 'b', 'c']) 
array = np.array([['a', 'a', 'c'], ['b', 'b', 'c']]) 

И я хотел бы заменить каждый элемент в array с индексом его значения в dictionary. Итак:

for index, value in enumerate(dictionary): 
    array[array == value] = index 
array = array.astype(int) 

Чтобы получить:

array([[0, 0, 2], 
     [1, 1, 2]]) 

Есть ли Векторизованный способ сделать это? Я знаю, что если array уже содержит индексы, и мне нужны строки в dictionary, я мог бы просто сделать dictionary[array]. Но мне действительно нужен «поиск» строк.

(я также вижу this answer, но интересно, если что-то новое было доступно с 2010 года)

ответ

2

Если ваш словарь сортируется, и словарь и массив содержит те же элементы, np.unique делает трюк

uniq, inv = np.unique(array, return_inverse=True) 
result = inv.reshape(array.shape) 

Если некоторые элементы отсутствуют в массиве:

uniq, inv = np.unique(np.r_[dictionary, array.ravel()], return_inverse=True) 
result = inv[len(dictionary):].reshape(array.shape) 

Общий случай:

uniq, inv = np.unique(np.r_[dictionary, array.ravel()], return_inverse=True) 
back = np.empty_like(inv[:len(dictionary)]) 
back[inv[:len(dictionary)]] = np.arange(len(dictionary)) 
result=back[inv[len(dictionary):]].reshape(array.shape) 

Объяснение: np.unique в виде мы используем его здесь возвращает уникальные элементы в отсортированном порядке и индексы в этот отсортированный список каждого элемента аргумента. Итак, чтобы получить индексы в исходном словаре, нам нужно переназначить индексы. Мы знаем, что uniq[inv[:len(uniq)]] == dictionary. Поэтому мы должны решить X[inv[:len(uniq)]] == np.arange(len(uniq)), что и делает код.

+0

Очень аккуратный! Спасибо. Подождите немного, чтобы узнать, есть ли у кого-то общее решение для не отсортированных словарей. (Вы вроде обойти необходимость поиска словаря вообще.) – capitalistcuttle

+0

@capitalistcuttle Последний бит («Общий случай») предназначен для не отсортированных словарей. –

+0

Ах, справа. Я еще не обнял его :). И я вижу, что он избегает сортировки словаря и использует сортированный вывод unique(). Большой! Кстати, в 2-й строке 2-го бит есть дополнительный прямоугольный кронштейн. И пара строк, описывающих косвенную обратную связь, была бы полезна. – capitalistcuttle

 Смежные вопросы

  • Нет связанных вопросов^_^