То, что вы пытаетесь достичь, называется «порог с гистерезисом».Для этого я адаптировал очень хороший алгоритм из этого ответа :
Учитывая ваши тестовые данные,
import numpy as np
array = np.array([-0.5, -2, -1, -0.5, -0.25, 0, 0, -2, -1, 0.25, 0.5, 1, 2])
вы определяете, какие значения ниже первого порога -1.0
и выше второго порога -0.3
:
low_values = array <= -1.0
high_values = array >= -0.3
Это значения, для которых вы знаете результат: либо 1
, либо 0
.Для всех других значений это зависит от его соседей.Таким образом, известны все значения, для которых low_values
или high_values
равно True
.Вы можете получить индексы всех известных элементов с помощью:
known_values = high_values | low_values
known_idx = np.nonzero(known_values)[0]
Чтобы найти результат для всех неизвестных значений, мы используем функцию np.cumsum
в массиве known_values
.Логические значения интерпретируются как 0
или 1
, поэтому это дает нам следующий массив:
acc = np.cumsum(known_values)
, что приведет к следующему для вашего примера: [ 0 1 2 2 3 4 5 6 7 8 9 10 11]
.Теперь known_idx[acc - 1]
будет содержать индекс последнего известного значения для каждой точки.С low_values[known_idx[acc - 1]]
вы получите True
, если последнее известное значение было ниже -1.0
, и False
, если оно было выше -0.3
:
result = low_values[known_idx[acc - 1]]
Осталась одна проблема: еслиначальное значение ниже -1.0
или выше -0.3
, тогда все работает отлично.Но если он находится между ними, он будет зависеть от своего левого соседа, которого у него нет.Так что в вашем случае вы просто определяете его как ноль.
Мы можем сделать это, проверив, равняется ли acc[0]
0
или 1
.Если acc[0] = 1
, то все в порядке, но если acc[0] = 0
, то это означает, что первое значение находится между -1.0
и -0.3
, поэтому мы должны установить его на ноль:
if not acc[0]:
result[0] = False
* 1053Наконец, поскольку мы много сравнивали, наш массив
result
является логическим массивом.Чтобы преобразовать его в целое число
0
и
1
, мы просто вызываем
result = np.int8(result)
и получаем желаемый результат:
array([0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0], dtype=int8)