Home > OS >  Find starting and end point of 1 in a list having 0s and 1s
Find starting and end point of 1 in a list having 0s and 1s

Time:11-11

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]]
  • Related