2017-09-27 19 views
3

我有一个元素列表,其中包含某些float类型的值。我想迭代元素并对它们进行计数,如果它们超过了某个值,而且只有在它们出现在阈值以上的最小值时间内才会对它们进行计数。因此,举例来说,如果有下列输入:如果超过某个值,计算元素

list_of_values = [2.0, 2.0, 2.0, 2.0, 0, 0, 2.0, 2.0, 2.0, 0, 0] 
treshold_value = 1.0 
minimum_count = 4 

答案应该是4,因为treshold_value 1.0只在指标连续0-3超出4倍。我现在有下面的代码,

for value in list_of_values: 
    if value >= treshold_value: 
     counter += 1 
    if counter >= (minimum_count): 
     time_use += 1 
    if value < min_treshold_value: 
     counter = 0 
print(time_use) 

我知道应该有实现这个:)

编辑一些Python的方式:在阈值的所有连续的子值的总和应该算。

+0

什么,如果'list_of_values'有'1.0'作为第一个项目?结果应该是什么? – RomanPerekhrest

+0

然后计数器增加1,因为1.0是> = treshold_value。所有值 ConSod

+0

如果有多于一个数字满足条件,例如'[2.0,2.0,2.0,2.0,0.0,3.0,2.0,2.0,2.0,10.0,0,0]'?如果结果是4,5或9? – mhawke

回答

1

你可以使用itertools.groupby()的帮助:

from itertools import groupby 

def count_runs(list_of_values, threshold_value=1.0, minimum_count=4): 
    count = 0 
    for k, g in groupby(list_of_values, key=lambda x: x >= threshold_value): 
     if k: 
      g = list(g) 
      if len(g) >= minimum_count: 
       count += len(g) 
    return count 

>>> count_runs([2.0, 2.0, 2.0, 0.0, 0, 0, 2.0, 2.0, 2.0, 0, 0]) 
0 
>>> count_runs([2.0, 2.0, 2.0, 2.0, 0, 0, 2.0, 2.0, 2.0, 0, 0]) 
4 
>>> count_runs([2.0, 2.0, 2.0, 2.0, 0, 0, 3.0, 2.0, 2.0, 2.0, 10.0, 0, 0]) 
9 

这将提供有值的数量的计数在minimum_count或更多的组的阈值以上。请注意,它处理符合条件的多个组。

例如,groupby()对于最后一个例子将返回以下:

>>> list_of_values = [2.0, 2.0, 2.0, 2.0, 0, 0, 3.0, 2.0, 2.0, 2.0, 10.0, 0, 0] 
>>> for k, g in groupby(list_of_values, key=lambda x: x >= threshold_value): 
...  print(k, list(g)) 
... 
True [2.0, 2.0, 2.0, 2.0] 
False [0, 0] 
True [3.0, 2.0, 2.0, 2.0, 10.0] 
False [0, 0] 

任何1个或更多个值的> =阈值将出现在一组与键True。只有那些长度> =最小数量的人才会被进一步考虑,其长度将与其他此类群组相符。

该代码可以写得更简洁,而且远远低于可读取,像这样:

def count_runs(list_of_values, threshold_value=1.0, minimum_count=4): 
    return sum(count for count in (len(list(g)) for k, g in groupby(list_of_values, key=lambda x: x >= threshold_value) if k) if count >= minimum_count) 
0

只是迭代列表并创建一个字典与键=浮点数和值=你遇到这个数字的次数。并且只添加到大于阈值的字典浮点数。是这样的:

d = {} 
for f in list_of_values : 
    if f > treshold: 
     if d.get(f,False): 
      d[f] +=1 
     else: 
      d[f] = 1 
max = 0 
for k,v in d.iteritems(): 
    if v> max: 
     max = v 

return max 
+0

好吧,你的for循环也有一个语法问题。 –

2

下使用groupby与条件发生器和max与相应的按键功能应该工作:

from itertools import groupby 

len(max((list(g) for k, g in groupby(list_ov, key=lambda x: x > threshold) if k), key=len)) 

groupby组可迭代通过连续的值相同WRT的关键功能。它会生成密钥值对并根据子迭代生成。

+2

LOL,在与妻子和母亲的假期徒步旅行...无聊致死,从手机上的应用程序发布:D必须已经检查维基文本框 – schwobaseggl

+0

哈哈,享受你的时间与这位太太。 –

+0

这个答案需要一些解释,以便对那些还不知道'groupby()'的人更有帮助。 – mhawke

0

看起来你不关心订单。在这种情况下,groupby不正确,因为它只对相邻元素进行分组。

你可以使用一个计数器和两个列表解析来过滤值:

list_of_values = [2.0, 2.0, 2.0, 2.0, 0, 0, 3.0, 2.0, 2.0, 2.0, 10.0, 0, 0] 
threshold_value = 1.0 
minimum_count = 4 

from collections import Counter 
counter = Counter([x for x in list_of_values if x > threshold_value]) 
print(counter) 
# Counter({2.0: 7, 3.0: 1, 10.0: 1}) 
print([(x, count) for x, count in counter.items() if count > minimum_count]) 
# [(2.0, 7)] 
相关问题