Clear way to check if n consecutive values out of N are bigger than a threshold and save their index (corresponding to n)

Question:

I would like to locate n consecutive points out of N from a vector of data with length L.
Example: 2 out 3 consecutive points bigger than a certain threshold tr.

data = [201,202,203, ..., L]
L = len(data)
N=3
tr = 200
for i in range(L-N+1):
    subset = data[i:i+N]
    if (subset[0] > tr and subset[1] > tr) or (subset[1] > tr and subset[2] > tr):
       "save index"

I would like to know how to save the index of the elements that satisfy such conditions?
Is there an elegant way to do it more flexibly (n out of N)?

Asked By: Pereira da Silva

||

Answers:

Start by flagging the items that are within the desired range. Then perform a rolling sum of the flags and select the matching indexes in subranges that have the minimum count of flagged items.

from itertools import islice

def getOver(data,minVal=200,minCount=2,window=3):
    inRange = [minVal<=n for n in data]
    groups  = (islice(inRange,s,None) for s in range(window))
    indexes = { i for s,r in enumerate(zip(*groups)) if sum(r)>=minCount
                for i in range(s,s+window) if inRange[i]}
    return sorted(indexes)

print(getOver([100,205,205]))
[1, 2]

print(getOver([201,205,205,150,190,203,100,205]))
[0, 1, 2, 5, 7]
Answered By: Alain T.

I just noticed that Alin T. answer is not completely correct. For example: getOver([203,100,205]) we will get [0,2], which is not quite correct as there’re not n (2) consecutive elements greater than a defined threshold (200). The output should be an empty array ([]).

Here is a solution:

def xoutXconsecutive(data, tr, n):
    out = []
    for i in range(0, len(data)-n+1):
        subset = np.array(data[i:i+n])
        isNotConsecutive = [False]*n
        for j in range(0, len(subset)):
            if (subset[j] < tr):
                isNotConsecutive[j] = True
        aux = False
        for k in range(1, len(isNotConsecutive)):
            if isNotConsecutive[k]:
                aux = True
                break
        if ( (isNotConsecutive[0] == False) and (aux == False) ):
            out += [i+(n-2), i+(n-1)]
        elif ( (isNotConsecutive[0] == True) and (aux == False)):
            out += [i+(n-1)]

    return np.unique(out)

print(xoutXconsecutive([203,100,205], 200, 3))

[]

Answered By: Pereira da Silva
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.