Самым простым и эффективным способом было бы избавиться от вызова np.nonzero
и использовать логическую индексацию так же, как в Matlab.Вот пример.(Я использую случайные данные той же формы, к вашему сведению.)
>>> data = np.random.randn(5, 5000)
>>> start, end = -0.5, 0.5
>>> ioi = (data[0] > start) & (data[0] < end)
>>> print(ioi.shape)
(5000,)
>>> print(ioi.sum())
1900
>>> print(data[:, ioi].shape)
(5, 1900)
Вызов np.nonzero
обычно не требуется.Как и функция Matlab find
, она медленнее по сравнению с логическим индексированием, и обычно цель может быть более эффективно достигнута с помощью логического индексирования.np.nonzero
, так же как и find
, следует в основном использовать только тогда, когда вам нужны сами фактические значения индекса.
Как вы и предполагали, причина дополнительных измерений заключается в том, что кортежи обрабатываются не так, как другие типыиндексирование массивов в NumPy.Это позволяет более гибко индексировать, например, с помощью slice
s, эллипсов и т. Д. Подробное объяснение см. на этой полезной странице , особенно в последнем разделе.
как минимум два других варианта решения проблемы.Одним из них является использование массива ioi
, возвращаемого из np.nonzero
, непосредственно в качестве индекса only для массива данных.Как в: self.data_array[ioi]
.Часть того, почему у вас есть дополнительное измерение, состоит в том, что у вас на самом деле есть два набора индексов в вашем вызове: срез (:
) и кортеж ioi
.np.nonzero
гарантированно вернет кортеж именно по этой причине, так что его вывод всегда можно будет использовать для прямого индексирования исходного массива.
Последний вариант - вызвать np.squeeze
для возвращаемого массива, ноЯ бы выбрал один из вышеперечисленных в первую очередь.