计算列表中连续真值的长度

时间:2017-09-17 20:29:32

标签: python list

基本上这个问题可以分为两部分。我有一组二进制值,表明给定的信号是否存在。鉴于每个值也对应于一个时间单位(在这种情况下是几分钟),我试图确定信号平均存在多长时间,因为它在我正在分析的整个期间内在整个值列表中出现。例如,如果我有以下列表:

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

我可以看到信号在可变长度的时间内发生3次不同的时间(即在第一种情况下持续3分钟)。如果我想计算每次出现的平均时间长度,我需要指示信号存在多少独立实例(即3)。我尝试了各种基于索引的策略,例如:

arb_ops.index(1)

找到下一个出现的真值并相应地找到下一个出现的0来查找长度,但是很难将其上下文化为整个数组的递归函数。

4 个答案:

答案 0 :(得分:3)

您可以使用itertools.groupby()对连续的相等元素进行分组。要计算组的长度,请将迭代器转换为列表并将len()应用于它:

>>> 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

答案 1 :(得分:0)

另一个选项可能是MaskedArray.count,它会计算沿给定轴的数组的非遮罩元素:

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 

你可以将Masked Arrays扩展到很远......

答案 2 :(得分:0)

与groupby的@ eugene-yarmash解决方案很不错。但是,如果您想使用不需要导入的解决方案,并且您自己进行分组 - 为了学习目的 - 您可以试试这个::

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

答案 3 :(得分:0)

我认为这个问题实际上很简单 - 如果你看到一个值是1,你知道你有一个新的信号,而前一个值是0。

我提供的代码很长,但非常简单,没有导入。

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)