Question: I'm trying to write a function that would detect all rising edges - indexes in a vector where value exceeds certain threshold. Something similar is described here: Python rising/falling edge oscilloscope-like trigger, but I want to add hysteresis, so that trigger won't fire unless the value goes below another limit. I came up the following code: import numpy as np arr = np.linspace(-10, 10, 60) sample_values = np.sin(arr) + 0.6 * np.sin(arr*3) above_trigger = sample_values > 0.6 below_deadband = sample_values < 0.0 combined = 1 * above_trigger - 1 * below_deadband  Now in the combined array there is 1 where the original value was above upper limit, -1 where the value was below lower limit and 0 where the value was in between: >>> combined array([ 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 0, 0, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 0, 0, 1, 1, 1, 0, -1, -1])  My idea was to use some clever function that would process this vector sequentially and replace all sequences of zeros with whatever non-zero value was preceding them. Then the problem would boil down to simply finding where the value changes from -1 to 1. I though that greater operation would fulfill this purpose if used correctly: -1 encoded as True and 1 as False:  (True ("-1") > -1) -> True ("-1") (True ("-1") > 1) -> False ("1") (True ("-1") > 0) -> True ("-1") (False ("1") > -1) -> True ("-1") (False ("1") > 1) -> False ("1") (False ("1") > 0) -> False ("1")  But the results are not what I expect: >>> 1 - 2 * np.greater.accumulate(combined) array([-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])  It seems that the greater function doesn't correctly compare booleans with numeric values in this scenario, even though it works fine when used on scalars or pair-wise: >>> np.greater(False, -1) True >>> np.greater.outer(False, combined) array([False, False, True, True, True, True, True, True, True, True, True, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, True, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True, False, False, False, False, False, False, False, False, False, True, True])  Is this expected behavior? Am I doing something wrong here, is there any way around this? Alternatively, maybe you could suggest another approach to this problem? Thank you.

Answer: I am not sure what the issue with np.greater.accumulate is (it does not seem to behave as advertised indeed), but the following should work: import numpy as np import numpy as np arr = np.linspace(-10, 10, 60) sample_values = np.sin(arr) + 0.6 * np.sin(arr*3) above_trigger = sample_values > 0.6 below_deadband = sample_values < 0.0 combined = 1 * above_trigger - 1 * below_deadband mask = combined != 0 idx = np.where(mask,np.arange(len(mask)),0) idx = np.maximum.accumulate(idx) result = combined[idx] print(f"combined:\n {combined}\n") print(f"result:\n {result}")  It gives: combined: [ 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 1 1 1 0 0 1 1 1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 1 1 1 0 0 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 0 0 1 1 1 0 -1 -1] result: [ 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 1 -1 -1]  Then the indices where values jumps from -1 to 1 can be obtained as follows: np.nonzero(result[1:] > result[:-1])[0] + 1  It gives: array([12, 31, 49])