Применение функции numpy take к 2d-массиву

#python #numpy #numpy-ndarray

#питон #numpy #numpy-ndarray

Вопрос:

У меня есть следующий 2d-массив numpy:

 array_a = np.array([[6.2, 2.0, 5.5, 8.0], [6.0, 5.1, 7.1, 8.2], ...])
 

У меня также есть список списков индексов (размеры списков различаются), представляющих значения, которые я хочу выбрать из этого массива.

 wanted_values = [[0,3], [1,2,3], ...]
 

В конце концов, я хочу иметь 2d-массив numpy, в котором каждая строка имеет только значения, соответствующие этим индексам. Желаемый результат будет выглядеть следующим образом:

 np.array([[6.2, 8.0], [5.1, 7.1, 8.2], ...])
 

Я преобразовал список индексов в массив numpy и выдал предупреждение о том, что «Создание ndarray из неровных вложенных последовательностей устарело». Затем я применил функцию take к массиву numpy и получил сообщение об ошибке:

 a.take(wanted_values) 
TypeError: Cannot cast array data from dtype('O') to dtype('int64') according to the rule 'safe'
 

Как я могу добиться желаемого результата? Есть ли лучший способ сделать это?

Комментарии:

1. Если вы предоставите полный пример кода, я могу просто запустить его и поиграть с ним 😉

2. У вас не может быть numpy-массива неправильной формы.

3. отбросьте numpy, используйте списки для вывода

4. Мне нужно позже применить функцию argmax к каждой из строк, поэтому предпочтительно придерживаться numpy

5. это не так, как работает numpy

Ответ №1:

Работайте с этим отсюда

 [array_a[i][wanted_values[i]] for i in range(len(wanted_values))]

#output

[array([6.2, 8. ]), array([5.1, 7.1, 8.2])]
 

Ответ №2:

У вас возникла проблема с размером строк в вашем массиве. Рассмотрим следующий пример

 >>> a = np.array([[1],[1,2]])
<stdin>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested 
sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different 
lengths or shapes) is deprecated. If you meant to do this, you must specify 
'dtype=object' when creating the ndarray
 

Более того, функция numpy take работает не так, как вы ожидаете. То есть, учитывая, что numpy допустил неровные вложенные последовательности, функция выполняет следующее:

  1. Это выравнивает массив ,
  2. он берет элементы из этого сплющенного массива, индексируемого числами внутри второго аргумента функции в вашем случае wanted_values , и размещает их таким же образом, в котором они размещены, wanted_values то есть ваш код даст np.array([6.2, 8.0],[2.0, 5.5, 8.0], ...]) то, что отличается от того, что вы ожидаете.

То, что я предлагаю вам сделать, это сохранить каждый выбор в списке choices, который вы создаете, повторяя обе итерации одновременно:

 array_a = np.array([[6.2, 2.0, 5.5, 8.0], [6.0, 5.1, 7.1, 8.2]])
wanted_values = [[0,3], [1,2,3]]
choice = []
for xs, indices in zip(array_a, wanted_values):
   choice.append(xs[indices])