在一系列日期中计算每月假布尔的数量?

时间:2015-11-29 20:36:43

标签: python python-2.7

我有一个如下列表,其中包含几个月内每个日期的布尔值。我想确定每个月的假布尔数,其最终目标是确定每月一次的错误"错误"每个月的百分比。例如,如果11月有15天假,我想在11月显示50%。怎么可以在Python中完成?

list = [('2015-11-01', False), ('2015-11-02', True), ('2015-11-03', True), ('2015-11-04', True), ('2015-11-05', True)]

2 个答案:

答案 0 :(得分:2)

将数据存储在dict中,使用年份作为外键按年份分组,并在每年计算您看到False的次数:

from collections import defaultdict
d = defaultdict(lambda: defaultdict(float))

from calendar import monthrange, month_name
for k, v in lst:
    year, mth, _ = k.split("-")
    d[int(year)][int(mth)] += not v

for year, dct in d.items():
    for mn, v in dct.items():
        _,  days = monthrange(year, mn)
        print("Average for {}-{} is {}".format(year, month_name[mn], v / days))

计算完毕后,您可以使用特定年份每月的正确天数来计算百分比。并非每年都有相同的每月天数,因此您无法使用通用日历来测试或忽略年份,日历模块会处理我们的日子。

创建一些随机数据:

from  random import choice

lst = [('2015-09-{}'.format(i), choice((True, False))) for i  in range(1,31)] + [('2015-11-{}'.format(i), choice((True, False))) for i  in range(1,31)]

输出:

Average for 2015-September is 0.533333333333
Average for 2015-November is 0.6

如果年份总是当年,那么您可以简化创建字典:

from collections import defaultdict
d = defaultdict(int)
for k, v in lst:
    year, mth,_= k.split("-")
    d[mth] += not v

print(d)

但请确保再次正确比较天数。

答案 1 :(得分:0)

此语句将返回一个长度为12的列表,其中包含变量“list”的每个月的True值数:

[sum([1 if int(pair[0][5:7]) == n and pair[1] else 0 for pair in list]) for n in range(1, 13)]

通过删除和语句,此语句将返回每个月的条目总数作为列表

[sum([1 if int(pair[0][5:7]) == n else 0 for pair in list]) for n in range(1, 13)]

通过结合前两个陈述,我们可以得到一个百分比列表:

trues = [sum([1 if int(pair[0][5:7]) == n and pair[1] else 0 for pair in list]) for n in range(1, 13)]
total = [sum([1 if int(pair[0][5:7]) == n else 0 for pair in list]) for n in range(1, 13)]
percentages = [trues[n] / float(total[n]) * 100 if total[n] != 0 else None for n in range(12)]

如果一个月有0个条目,它将返回无

- 编辑 -

我将此解释为看到某个月输入的所有值的百分比为True,但是如果您要查找该值中标记为True的值的所有日期的百分比,只需更改总变量到:

total = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

(假设非闰年)