Ответ 1
В Python (1)
означает просто 1
. ()
можно свободно добавлять к номерам групп и выражениям для удобочитаемости человека (например, (1+3)*3
v (1+3,)*3
). Таким образом, для обозначения 1-элементного кортежа он использует (1,)
(и требует, чтобы вы также использовали его).
Таким образом,
(array([4, 5, 6, 7, 8]),)
- это один элемент, который является массивом.
Если вы применили where
к 2d-массиву, результатом будет 2-элементный кортеж.
Результат where
таков, что он может быть подключен непосредственно к слоту индексирования, например.
a[where(a>0)]
a[a>0]
должен возвращать те же самые вещи
как и
I,J = where(a>0) # a is 2d
a[I,J]
a[(I,J)]
Или с вашим примером:
In [278]: a=np.array([1,2,3,4,5,6,7,8,9])
In [279]: np.where(a>4)
Out[279]: (array([4, 5, 6, 7, 8], dtype=int32),) # tuple
In [280]: a[np.where(a>4)]
Out[280]: array([5, 6, 7, 8, 9])
In [281]: I=np.where(a>4)
In [282]: I
Out[282]: (array([4, 5, 6, 7, 8], dtype=int32),)
In [283]: a[I]
Out[283]: array([5, 6, 7, 8, 9])
In [286]: i, = np.where(a>4) # note the , on LHS
In [287]: i
Out[287]: array([4, 5, 6, 7, 8], dtype=int32) # not tuple
In [288]: a[i]
Out[288]: array([5, 6, 7, 8, 9])
In [289]: a[(i,)]
Out[289]: array([5, 6, 7, 8, 9])
======================
np.flatnonzero
показывает правильный способ возврата только одного массива, независимо от размеров входного массива.
In [299]: np.flatnonzero(a>4)
Out[299]: array([4, 5, 6, 7, 8], dtype=int32)
In [300]: np.flatnonzero(a>4)+10
Out[300]: array([14, 15, 16, 17, 18], dtype=int32)
В нем говорится:
Это эквивалентно a.ravel(). nonzero() [0]
Фактически это буквально то, что делает функция.
Сглаживание a
устраняет вопрос о том, что делать с несколькими измерениями. И затем он берет ответ из кортежа, предоставляя вам простой массив. С уплощением он не имеет особого случая для 1-го массива.
===========================
@Дивакар предлагает np.argwhere
:
In [303]: np.argwhere(a>4)
Out[303]:
array([[4],
[5],
[6],
[7],
[8]], dtype=int32)
который делает np.transpose(np.where(a>4))
Или, если вам не нравится вектор-столбец, вы можете перенести его снова
In [307]: np.argwhere(a>4).T
Out[307]: array([[4, 5, 6, 7, 8]], dtype=int32)
за исключением того, что теперь это 1xn массив.
Мы могли бы просто обернуть where
в array
:
In [311]: np.array(np.where(a>4))
Out[311]: array([[4, 5, 6, 7, 8]], dtype=int32)
Множество способов выделения массива из кортежа where
([0]
, i,=
, transpose
, array
и т.д.).