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)?
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]
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))
[]
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)?
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]
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))
[]