将日期列表分成几天 [英] Split list of datetimes into days

查看:119
本文介绍了将日期列表分成几天的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数据表的排序列表:(有日间差距)

  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),
]

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

  result = [
[datetime.datetime(2012,1,1,0,0,0)),datetime .datetime(2012,1,1,0,0)],
[datetime.datetime(2012,1,2,0,0,0)],
[datetime.datetime(2012 ,1,3,0,0,0)],
[],#一天中没有datetimes的空列表
[datetime.datetime(2012,1,5,0,0,0)]
]

从算法上看,应该可以至少达到O(n) / p>

也许如下所示:
(Th显然不会处理错过的日子,并且丢弃最后一个dt,但这是一个开始)

  def dt_to_d(list_of_dts): 
result = []
start_dt = list_of_dts [0]
day = [start_dt]
for i,dt in枚举(list_of_dts [1:]):
上一个= start_dt if i == 0 else list_of_dts [i-1]
如果dt.day>上一个或第二个月上一个月或者年月日前一年:
#拆分为新子列表
result.append(day)
day = []
#每天间隔循环?
day.append(dt)
返回结果

想法?

解决方案

最简单的方法是使用 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 range 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, ,0,0)],
[],
[datetime.datetime(2012,1,5,0,0)]]

进行此类分组的另一种方法是 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)]]


I've got a sorted list of datetimes: (with day gaps)

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),
              ]

And I'd like to split them in to a list for each day:

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)]
         ]

Algorithmically, it should be possible to achieve at least O(n).

Perhaps something like the following: (This obviously doesn't handle missed days, and drops the last dt, but it's a start)

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

Thoughts?

解决方案

The easiest way to go is to use dict.setdefault to group entries falling on the same day and then loop over the lowest day to the highest:

>>> 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)]]

Another approach for making such groupings is itertools.groupby. It is designed for this kind of work, but it doesn't provide a way to fill-in an empty list for missing days:

>>> 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)]]

这篇关于将日期列表分成几天的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆