Функция, аналогичная numpy.take, индексирует выходной параметр
В документации numpy.take
заявлено, что a
индексируется в соответствии с indices
а также axis
затем результат может быть сохранен в out
параметр. Существует ли функция, которая выполняет индексацию out
вместо? Используя необычное индексирование, это будет что-то вроде:
out[:, :, indices, :] = a
Здесь я предполагаю, что axis=2
но в моем случае я не знаю оси заранее. Также приемлемо решение с использованием 1d логических масок вместо индексов.
2 ответа
Вы можете использовать swapaxes следующим образом:
>>> A = np.arange(24).reshape(2,3,4)
>>> out = np.empty_like(A)
>>> I = [2,0,1]
>>> axis = 1
>>> out.swapaxes(0, axis)[I] = A.swapaxes(0, axis)
>>> out
array([[[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 0, 1, 2, 3]],
[[16, 17, 18, 19],
[20, 21, 22, 23],
[12, 13, 14, 15]]])
Некоторые из numpy
Функции создают индексный кортеж при работе на указанной оси.
Код не очень красивый, но общий и достаточно эффективный.
In [700]: out = np.zeros((2,1,4,5),int)
In [701]: out
Out[701]:
array([[[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]],
[[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]]])
In [702]: indices = [3,0,1]
Сделайте кортеж индексации. Начните со списка или массива для простоты построения, а затем преобразуйте в tuple
при индексации:
In [703]: idx = [slice(None)]*out.ndim
In [704]: idx[2] = indices
In [705]: idx
Out[705]:
[slice(None, None, None),
slice(None, None, None),
[3, 0, 1],
slice(None, None, None)]
In [706]: out[tuple(idx)] = 10
In [707]: out
Out[707]:
array([[[[10, 10, 10, 10, 10],
[10, 10, 10, 10, 10],
[ 0, 0, 0, 0, 0],
[10, 10, 10, 10, 10]]],
[[[10, 10, 10, 10, 10],
[10, 10, 10, 10, 10],
[ 0, 0, 0, 0, 0],
[10, 10, 10, 10, 10]]]])
Это соответствует take
:
In [708]: np.take(out, indices, axis=2)
Out[708]:
array([[[[10, 10, 10, 10, 10],
[10, 10, 10, 10, 10],
[10, 10, 10, 10, 10]]],
[[[10, 10, 10, 10, 10],
[10, 10, 10, 10, 10],
[10, 10, 10, 10, 10]]]])
Мы можем установить более сложные значения при условии правильной трансляции:
out[tuple(idx)] = np.array([10,11,12])[...,None]
Я также видел numpy
функции, которые перемещают ось интереса в известное место - начало или конец. В зависимости от действия может потребоваться замена.
Есть такие функции, как place
, put
, copyto
которые предоставляют другие способы управления присваиванием (помимо обычной индексации). Но никто не берет axis
параметр как np.take
,