将日期时间列表拆分为天

Ale*_*x L 10 python grouping datetime date

我有一个日期排序列表:(有日间隔)

list_of_dts = [
              datetime.datetime(2012,1,1,0,0,0), 
              datetime.datetime(2012,1,1,1,0,0), 
              datetime.datetime(2012,1,2,0,0,0), 
              datetime.datetime(2012,1,3,0,0,0),
              datetime.datetime(2012,1,5,0,0,0),
              ]
Run Code Online (Sandbox Code Playgroud)

而且我想将它们分成每天的列表:

result = [
          [datetime.datetime(2012,1,1,0,0,0), datetime.datetime(2012,1,1,1,0,0)],
          [datetime.datetime(2012,1,2,0,0,0)],
          [datetime.datetime(2012,1,3,0,0,0)],
          [], # Empty list for no datetimes on day
          [datetime.datetime(2012,1,5,0,0,0)]
         ]
Run Code Online (Sandbox Code Playgroud)

在算法上,应该可以实现至少O(n).

也许类似于以下内容:(这显然不会处理错过的日子,并且丢弃最后的dt,但这是一个开始)

def dt_to_d(list_of_dts):
    result = []
    start_dt = list_of_dts[0]
    day = [start_dt]
    for i, dt in enumerate(list_of_dts[1:]):
        previous = start_dt if i == 0 else list_of_dts[i-1]
        if dt.day > previous.day or dt.month > previous.month or dt.year > previous.year: 
            # split to new sub-list
            result.append(day)
            day = []
            # Loop for each day gap?
        day.append(dt)
    return result
Run Code Online (Sandbox Code Playgroud)

思考?

Ray*_*ger 12

最简单的方法是使用dict.setdefault对同一天下降的条目进行分组,然后将最低日期循环到最高日期:

>>> import datetime
>>> list_of_dts = [
              datetime.datetime(2012,1,1,0,0,0),
              datetime.datetime(2012,1,1,1,0,0),
              datetime.datetime(2012,1,2,0,0,0),
              datetime.datetime(2012,1,3,0,0,0),
              datetime.datetime(2012,1,5,0,0,0),
              ]

>>> days = {}
>>> for dt in list_of_dts:
        days.setdefault(dt.toordinal(), []).append(dt)

>>> [days.get(day, []) for day in range(min(days), max(days)+1)]
[[datetime.datetime(2012, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 1, 0)], 
 [datetime.datetime(2012, 1, 2, 0, 0)],
 [datetime.datetime(2012, 1, 3, 0, 0)],
 [],
 [datetime.datetime(2012, 1, 5, 0, 0)]]
Run Code Online (Sandbox Code Playgroud)

制作此类分组的另一种方法是itertools.groupby.它专为此类工作而设计,但它没有提供填写缺失日期的空列表的方法:

>>> import itertools
>>> [list(group) for k, group in itertools.groupby(list_of_dts,
                                                   key=datetime.datetime.toordinal)]
[[datetime.datetime(2012, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 1, 0)], 
 [datetime.datetime(2012, 1, 2, 0, 0)],
 [datetime.datetime(2012, 1, 3, 0, 0)],
 [datetime.datetime(2012, 1, 5, 0, 0)]]
Run Code Online (Sandbox Code Playgroud)

  • 甚至比`setdefault`更简单可以是`defaultdict`(来自`collections`). (2认同)

qia*_*iao 5

您可以使用itertools.groupby轻松处理此类问题:

import datetime
import itertools

list_of_dts = [
        datetime.datetime(2012,1,1,0,0,0), 
        datetime.datetime(2012,1,1,1,0,0), 
        datetime.datetime(2012,1,2,0,0,0), 
        datetime.datetime(2012,1,3,0,0,0),
        datetime.datetime(2012,1,5,0,0,0),
        ]

print [list(g) for k, g in itertools.groupby(list_of_dts, key=lambda d: d.date())]
Run Code Online (Sandbox Code Playgroud)