Найдите первый индекс, для которого массив опускается ниже определенного порога (и оставайтесь ниже некоторое время) - PullRequest
0 голосов
/ 05 сентября 2018

Пусть A будет одномерный массив, порог t и длина окна K.

Как найти минимальный индекс j, такой, что A[j:j+K] < t? (т. Е. Первый раз, когда A остается ниже порога в полном окне ширины K ).

Я пробовал (незаконченные) вещи с помощью цикла, но он казался далеко не оптимальным, и я подумал, что, может быть, есть хитрый "тупой способ" сделать это.


Sidenote: тот факт, что мы хотим проверить, не находимся ли мы ниже порога в течение определенной длины окна вместо понятийного значения, полезен, чтобы избежать включения / выключения / включения / выключения / включения / выключения артефактов вблизи порога (см. также Гистерезис : "гистерезис преднамеренно добавляется в электронную схему, чтобы предотвратить нежелательное быстрое переключение [...], компенсирующее отскок контактов в переключателях или шум в электрическом сигнале. «).

1 Ответ

0 голосов
/ 05 сентября 2018

Подход № 1

Мы можем использовать 1D convolution -

np.flatnonzero(np.convolve(A<t, np.ones(K,dtype=int))==K)[0]-K+1

Идея состоит в том, чтобы получить логический массив после сравнения с пороговым значением, а затем запустить 1D свертку с ядром длины, равной window, заполненной 1s. Это дает нам сумму каждого скользящего окна. Итак, все окна, которые имеют сумму K, являются теми, которые мы ищем. Используйте flatnonzero, чтобы получить начальные индексы для действительных окон. Наконец, выберите первый.

Подход № 2

С binary-erosion -

from scipy.ndimage.morphology import binary_erosion

np.flatnonzero(binary_erosion(A<t, np.ones(K), origin=-(K//2)))[0]

Это запускает скользящее ядро ​​с длиной, равной window, и стирает все окна, которые не имеют последовательностей window длины True, оставляя нас с действительными. Опять же, используйте flatnonzero, чтобы получить индексы и, наконец, выбрать первый. Нам нужно использовать arg origin с двоичной эрозией, чтобы мы выбирали пуски.

Подход № 3

Вот еще один с поиском острова -

# Get mask of valid elements with comparison against thresh
mask = np.r_[False,A<t,False]

# Get indices of starts and ends for the valid islands
idx = np.flatnonzero(mask[:-1] != mask[1:])
start,stop = idx[::2],idx[1::2]

# Get the island lengths and check for lengths >=K and mask  start indices
# and select the first one among them
out = start[(stop - start)>=K][0]
...