简体   繁体   中英

Compute the length of consecutive true values in a list

Essentially this problem can be split into two parts. I have a set of binary values that indicate whether a given signal is present or not. Given that the each value also corresponds to a unit of time (in this case minutes) I am trying to determine how long the signal exists on average given its occurrence within the overall list of values throughout the period I'm analyzing. For example, if I have the following list:

[0,0,0,1,1,1,0,0,1,0,0,0,1,1,1,1,0]

I can see that the signal occurs 3 separate times for variable lengths of time (ie in the first case for 3 minutes). If I want to calculate the average length of time for each occurrence however I need an indication of how many independent instances of the signal exist (ie 3). I have tried various index based strategies such as:

arb_ops.index(1)

to find the next occurrence of true values and correspondingly finding the next occurrence of 0 to find the length but am having trouble contextualizing this into a recursive function for the entire array.

You could use itertools.groupby() to group consecutive equal elements. To calculate a group's length convert the iterator to a list and apply len() to it:

>>> from itertools import groupby
>>> lst = [0 ,0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0 ,1, 1, 1, 1, 0]
>>> for k, g in groupby(lst):
...     g = list(g)
...     print(k, g, len(g))
... 
0 [0, 0, 0] 3
1 [1, 1, 1] 3
0 [0, 0] 2
1 [1] 1
0 [0, 0, 0] 3
1 [1, 1, 1, 1] 4
0 [0] 1

Another option may be MaskedArray.count , which counts non-masked elements of an array along a given axis:

import numpy.ma as ma
a = ma.arange(6).reshape((2, 3))
a[1, :] = ma.masked
a
masked_array(data =
[[0 1 2]
[-- -- --]],
mask =
[[False False False]
[ True  True  True]],
fill_value = 999999)
a.count()
3 

You can extend Masked Arrays quite far...

@eugene-yarmash solution with the groupby is decent. However, if you wanted to go with a solution that requires no import, and where you do the grouping yourself --for learning purposes-- you could try this::

>>> l = [0,0,0,1,1,1,0,0,1,0,0,0,1,1,1,1,0]
>>> def size(xs):                                                                                                                                             
...     sz = 0                                                                                                                                                
...     for x in xs:                                                                                                                                          
...         if x == 0 and sz > 0:                                                                                                                             
...             yield sz
...             sz = 0
...         if x == 1:                                                                                                                                        
...             sz += 1                                                                                                                                       
...     if sz > 0:
...         yield sz
...
>>> list(size(l))
[3, 1, 4]

I think this problem is actually pretty simple--you know you have a new signal if you see a value is 1, and the previous value is 0.

The code I provided is kind of long, but super simple, and done without imports.

signal = [0,0,0,1,1,1,0,0,1,0,0,0,1,1,1,1,0]

def find_number_of_signals(signal):
    index = 0
    signal_counter = 0
    signal_duration = 0
    for i in range(len(signal) - 1):

        if signal[index] == 1:
            signal_duration += 1.0
            if signal[index- 1] == 0:
                signal_counter += 1.0

        index += 1

    print signal_counter
    print signal_duration
    print float(signal_duration / signal_counter)


find_number_of_signals(signal)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM