使用日期时间聚合字典

时间:2019-01-31 13:51:40

标签: python datetime dictionary

我有一个字典WO,其格式为:

WO = {datetime: {'V1', 'V2', 'V3', 'V4'}}

datetime是(示例)格式的键:

datetime.date(2014, 6, 20)

V1V4是包含浮点值的列表。

示例:

WO = {datetime.date(2014, 12, 20): {'V1': [11, 15, 19], 
                                    'V2': [12, 3, 4], 
                                    'V3': [50, 55, 56], 
                                    'V4': [100, 112, 45]},
      datetime.date(2014, 12, 21): {'V1': [10, 12, 9], 
                                    'V2': [16, 13, 40], 
                                    'V3': [150, 155, 156], 
                                    'V4': [1100, 1132, 457]},
      datetime.date(2014, 12, 22): {'V1': [107, 172, 79], 
                                    'V2': [124, 43, 44], 
                                    'V3': [503, 552, 561], 
                                    'V4': [1000, 1128, 457]}}

如果我想根据给定日期的星期从V1V4汇总值,例如:

my_date = datetime.date(2014, 5, 23)

对于这个给定的日期,将本周从星期一开始的V1V4的所有值进行汇总。

year, week, weekday = datetime.date(my_date).isocalendar()

此行为我提供了该特定日期的星期和工作日。

如果我有以下功能:

def week(date):
    '''
    date is in 'datetime.date(year, month, date)' format

    This function is supposed to aggregate values in 'V1', 'V2', 'V3' and 
    'V4' for a whole week according to the parameter 'date'
    '''

接下来我应该如何定义这样的功能?

3 个答案:

答案 0 :(得分:1)

根据我的理解,

您想对给定日期的给定周的所有V1 ... V4值进行一些操作。 首先,我将从找到给定日期的星期一(星期开始)开始。

year, week, weekday = my_date.isocalendar()     
last_monday_date = my_date - datetime.timedelta(days = weekday - 1)

会给你最后一个星期一的日期。

然后您可以将其用于工作日内的日期范围: Creating a range of dates in Python

最后在循环的日期范围内,迭代WO值并获得结果。

答案 1 :(得分:0)

如果我将缺少的花括号添加到WO中以消除语法错误(在发布之前您应该确实检查过):

WO = {datetime.date(2014, 12, 20): {'V1': [11, 15, 19], 'V2': [12, 3, 4], 'V3': [50, 55, 56], 'V4': [100, 112, 45]}, datetime.date(2014, 12, 22): {'V1': [107, 172, 79], 'V2': [124, 43, 44], 'V3': [503, 552, 561], 'V4': [1000, 1128, 457]}, datetime.date(2014, 12, 21): {'V1': [10, 12, 9], 'V2': [16, 13, 40], 'V3': [150, 155, 156], 'V4': [1100, 1132, 457]}}

然后我可以执行此操作以查看数据中的星期几:

>>> for date, values in WO.items():
        year, week, _ = date.isocalendar()
        print (date,year,week)

我可以看到在此示例中,您有两个星期要汇总:

2014-12-20 2014 51
2014-12-22 2014 52
2014-12-21 2014 51

也就是说,您的数据与2014年的ISO第51和52周有关。您将按周进行合并,因此汇总数据将具有键(year, week),但没有日期。 (您需要年份,因为数据中的年份可能不同。)因此,您正在寻找使用键dict(2014, 51)构建(2014, 52)。一个将具有与"V1"-"V4"关联的3个值,因为该周只有一天,没有可合并的内容。另一周将有6个与"V1"-"V4"关联的值,因为数据中该周有两天。

以空的dict开头以包含摘要:

>>> summary = {}

像往常一样浏览日期以查找年和周,但是这次根据(year, week)键来收集数据:

>>> for date, values in WO.items():
      year, week, _ = date.isocalendar()
      if (year, week) not in summary:
        summary [(year, week)] = {vn: [] for vn in values} # empty lists for vn = 'V1' - 'V4'
      for vn in values:
        summary[(year, week)][vn].extend(values[vn])

>>> summary
{(2014, 51): {'V1': [11, 15, 19, 10, 12, 9], 'V2': [12, 3, 4, 16, 13, 40], 'V3': [50, 55, 56, 150, 155, 156], 'V4': [100, 112, 45, 1100, 1132, 457]}, (2014, 52): {'V1': [107, 172, 79], 'V2': [124, 43, 44], 'V3': [503, 552, 561], 'V4': [1000, 1128, 457]}}

答案 2 :(得分:0)

您可以使用嵌套的defaultdict来收集同一周的数据,并使用周号作为键(或其他一些可哈希的标识符)。然后使用嵌套的字典理解以元素的方式对列表列表求和。

from collections import defaultdict

dd = defaultdict(lambda: defaultdict(list))

for k1, v1 in WO.items():
    for k2, v2 in v1.items():
        dd[k1.isocalendar()[1]][k2].append(v2)

WO_agg = {k1: {k2: list(map(sum, zip(*v2))) for k2, v2 in v1.items()} \
          for k1, v1 in dd.items()}

print(WO_agg)
# {51: {'V1': [21, 27, 28],
#       'V2': [28, 16, 44],
#       'V3': [200, 210, 212],
#       'V4': [1200, 1244, 502]},
#  52: {'V1': [107, 172, 79],
#       'V2': [124, 43, 44],
#       'V3': [503, 552, 561],
#       'V4': [1000, 1128, 457]}}