繁体   English   中英

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

[英]Compute the length of consecutive true values in a 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来找到长度,但是在将其上下文化为整个数组的递归函数时遇到了麻烦。

您可以使用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

另一个选项可能是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扩展得很远...

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

我认为这个问题实际上很简单-如果知道值是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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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