I have a list and I want to find the starting and ending index of value 1. Here is the list
labels=[0,0,0,1,1,1,0,0,1,1]
The 1s index are [3,5]
and [8,9]
Is there any efficient way to do this. I have tried numpy index(), but it did not work for me. Using it, either i can find first or last 1, but not the ones in middle. This is what I have tried.
[labels.index(1),len(labels)-labels[::-1].index(1)-1]
This gives me [3,9]
but i want to have indexes of consecutive 1s which is [3,5]
and [8,9]
CodePudding user response:
One option, get the start of each stretch using diff
and comparison to 0 after padding to ensure that the labels start and end with 0:
labels = [0,0,0,1,1,1,0,0,1,1]
out = np.where(np.diff(np.pad(labels, 1))!=0)[0].reshape(-1,2)-[0,1]
output:
array([[3, 5],
[8, 9]])
As list:
out.tolist()
# [[3, 5], [8, 9]]
CodePudding user response:
The approach suggested by @mozway may be better suited to large lists. However, for such a small data set, this method is considerably faster (if that's important):
labels = [0, 0, 0, 1, 1, 1, 0, 0, 1, 1]
def func(labels):
result = []
se = -1
for i, e in enumerate(labels):
if e == 1:
if se < 0:
se = i
else:
if se >= 0:
result.append([se, i-1])
se = -1
if se >= 0:
result.append([se, len(labels)-1])
return result
print(func(labels))
Output:
[[3, 5], [8, 9]]
CodePudding user response:
One way of doing it by using itertools compress, groupby and count. "Get indices of 1, group by consecutive indices and find first and last indice in group".
from itertools import groupby, compress, count
serie = [0,0,0,1,1,1,0,0,1,1,0,1,0]
stream = compress(*zip(*enumerate(serie))) # indices of 1
consecutives = ([*streak] for _, streak in groupby(stream, lambda n, c=count(): n - next(c))) # streaks of consecutive numbers
indices = [[el[0], el[-1]] for el in consecutives]
-> [[3, 5], [8, 9], [11, 11]]