Вам необходимо иметь четкое представление о том, что производит nonzero
, и обратить внимание на разницу между индексацией списком (списками) и кортежем.
===
In [110]: somearray = np.array([1,2,3,4,5,6])
...: arrayindex = np.nonzero(somearray > 4)
nonzero
создает набор массивов, по одному на измерение (это становится более очевидным с 2d массивами):
In [111]: arrayindex
Out[111]: (array([4, 5]),)
Это может использоваться непосредственно в качестве индекса:
In [113]: somearray[arrayindex]
Out[113]: array([5, 6])
В этом 1d-случае вы можете извлечь массив из кортежа и выполнить итерации по нему:
In [114]: for i in arrayindex[0]:print(i, somearray[i])
4 5
5 6
argwhere
делает 'transpose', который также может быть использован для итерации
In [115]: idxs = np.argwhere(somearray>4)
In [116]: idxs
Out[116]:
array([[4],
[5]])
In [117]: for i in idxs: print(i,somearray[i])
[4] [5]
[5] [6]
idxs
- это (2,1) форма, поэтому i
- это (1,) массив формы, в результате чего на дисплее отображаются скобки , Иногда это полезно, но nonzero
используется чаще (часто под другим именем, np.where
).
2d
argwhere
имеет 2d пример:
In [119]: x=np.arange(6).reshape(2,3)
In [120]: np.argwhere(x>1)
Out[120]:
array([[0, 2],
[1, 0],
[1, 1],
[1, 2]])
In [121]: np.nonzero(x>1)
Out[121]: (array([0, 1, 1, 1]), array([2, 0, 1, 2]))
In [122]: x[np.nonzero(x>1)]
Out[122]: array([2, 3, 4, 5])
Хотя nonzero
можно использовать для индексации массива, элементы argwhere
не могут.
In [123]: for ij in np.argwhere(x>1):
...: print(ij,x[ij])
...:
...
IndexError: index 2 is out of bounds for axis 0 with size 2
Проблема в том, что ij
- это список, который используется для индексации по измерению. numpy
различает списки и кортежи при индексации. (В более ранних версиях различие исчезло, но в текущих версиях используется более строгий подход.)
Поэтому нам нужно преобразовать список в кортеж. Один из способов - распаковать его:
In [124]: for i,j in np.argwhere(x>1):
...: print(i,j,x[i,j])
...:
...:
0 2 2
1 0 3
1 1 4
1 2 5
Я мог бы использовать: print(ij,x[tuple(ij)])
в [123].
Я должен был использовать распаковку итерации [117]:
In [125]: for i, in idxs: print(i,somearray[i])
4 5
5 6
или somearray[tuple(i)]