Две проблемы:
- используйте
np.where
вместо argwhere
; вам не нужно повторять - полученные индексы применяются к срезу, а не к исходному массиву
С вашим массивом:
In [133]: arr = np.array([[[0., 1., 43., 25., 21.],
...: [0., 0., 0., 0., 0.],
...
...: [0., 26., 0., 0., 1.],
...: [0., 30., 1., 1., 0.]]])
...:
срез:
In [136]: subarr = arr[:,2:,2:]
, где значения среза равны 1:
In [137]: np.nonzero(subarr==1)
Out[137]:
(array([0, 0, 0, 0, 1, 1, 1, 1]),
array([0, 1, 1, 2, 0, 1, 2, 2]),
array([1, 0, 2, 1, 2, 2, 0, 1]))
Это похоже на ваш argwhere
, за исключением кортежа массивов, а не смещения.
In [138]: values = [[2, 3, 1, 4],
...: [4, 1, 5, 9]]
...:
Этот кортеж можно использовать для индексации среза как для выборки, так и для установки:
In [139]: subarr[np.nonzero(subarr==1)]
Out[139]: array([1., 1., 1., 1., 1., 1., 1., 1.])
In [140]: subarr[np.nonzero(subarr==1)]=np.ravel(values)
Поскольку subarr
является представлением, установка значений в нем также устанавливает значения в arr
. Нет необходимости преобразовывать индексы в структуру arr
.
In [141]: arr
Out[141]:
array([[[ 0., 1., 43., 25., 21.],
[ 0., 0., 0., 0., 0.],
[ 0., 43., 0., 2., 0.],
[ 0., 43., 3., 0., 1.],
[ 0., 45., 0., 4., 0.]],
[[ 0., 1., 38., 29., 46.],
[ 0., 0., 0., 0., 0.],
[ 0., 32., 0., 0., 4.],
[ 0., 26., 0., 0., 1.],
[ 0., 30., 5., 9., 0.]]])
логическое индексирование
Как и другие примечания к ответу, мы можем выбирать элементы с помощью логической маски без nonzero
шаг (под обложками индексация похожа, если не идентична).
In [144]: arr = np.array([[[0., 1., 43., 25., 21.],
...: [0., 0., 0., 0., 0.],
...
...: [0., 30., 1., 1., 0.]]])
...:
In [145]: subarr = arr[:,2:,2:]
In [146]: subarr[subarr==1]
Out[146]: array([1., 1., 1., 1., 1., 1., 1., 1.])
In [148]: subarr[subarr==1] = np.ravel(values)
In [149]: arr
Out[149]:
array([[[ 0., 1., 43., 25., 21.],
[ 0., 0., 0., 0., 0.],
....
[ 0., 30., 5., 9., 0.]]])
ближе к вашей попытке
На самом деле ваша итерация могла бы сработать, если бы вы повторили indices
:
for i,v in zip(idx,np.ravel(values)):
arr[tuple(i)] == v
Начиная с моего where
кортежа:
In [159]: Out[137]
Out[159]:
(array([0, 0, 0, 0, 1, 1, 1, 1]),
array([0, 1, 1, 2, 0, 1, 2, 2]),
array([1, 0, 2, 1, 2, 2, 0, 1]))
In [160]:
Ваше смещение argwhere
:
In [160]: idx = np.transpose(Out[137])+[0,2,2]
In [161]: idx
Out[161]:
array([[0, 2, 3],
[0, 3, 2],
[0, 3, 4],
[0, 4, 3],
[1, 2, 4],
[1, 3, 4],
[1, 4, 2],
[1, 4, 3]])
Используя это итеративно для индексации arr
(примечание использование tuple
):
In [162]: [arr[tuple(i)] for i in idx]
Out[162]: [2.0, 3.0, 1.0, 4.0, 4.0, 1.0, 5.0, 9.0]
Итерация непосредственно на values
не работает, так как это возвращает 2 списка. Его нужно сплющить / разгладить.
In [163]: for v in values: print(v)
[2, 3, 1, 4]
[4, 1, 5, 9]