生成Python的datetime.time对象数组

3
我该如何从这两个对象生成一个datetime.time对象的数组:
start = datetime.time(22, 0)
end   = datetime.time( 2, 0)

那将会看起来像:
interval = array([datetime.time(22,0), datetime.time(23,0), datetime.time(0,0),
                  datetime.time( 1,0), datetime.time( 2,0)])

编辑

在这个例子中,增量是小时=1,但它可能是分钟或秒。我正在寻找类似于 pandas.date_range 的东西。


这看起来像是你想要一个“列表”,而不是一个“数组”。 - juanpa.arrivillaga
编辑中有错别字('loking')。 - SwiftsNamesake
4个回答

1
更新:使用numpy的简短版本
import datetime
import numpy as np

def return_times(start,end):
    if start < end:
        return np.array([datetime.time(i,0) for i in range(start.hour,end.hour+1)])
    else:
        hours = list(range(24))
        nplist = np.array([datetime.time(i,0) for i in hours if i not in list(range(end.hour+1,start.hour))])
        return np.roll(nplist, -np.where(nplist==start)[0][0])

return_times(datetime.time(0,0),datetime.time(3,0)) # if-case 1
return_times(datetime.time(22,0),datetime.time(2,0)) # else-case

00:00 -> 03:00

array([datetime.time(0, 0), datetime.time(1, 0), datetime.time(2, 0),
   datetime.time(3, 0)], dtype=object)

100000次循环,3次中最佳表现:每次循环12.6微秒

22:00 -> 02:00

array([datetime.time(22, 0), datetime.time(23, 0), datetime.time(0, 0),
       datetime.time(1, 0), datetime.time(2, 0)], dtype=object)

10000次循环,3次中最佳:每个循环79.9微秒。

更新2 由于SwiftsNamesake的帮助,这可以在一个列表理解中解决。

import datetime

def return_times(start,end):
    s  = start.hour
    e  = end.hour 
    hours = [i%24 for i in range(s, e+1 if e >= s else 24+e+1)]
    return [datetime.time(i,0) for i in hours]

return_times(datetime.time(0,0),datetime.time(3,0))

100000次循环,3次中最优结果:每个循环需要3.75微秒。

1
这比它需要的更复杂,我认为。 - SwiftsNamesake
1
[i%24 for i in range(s, e + 1 + (0 if e >= s else 24))] - SwiftsNamesake
hours = [...] - SwiftsNamesake
像这样吗?因为它不更快(但我猜更有效率?)hours = (i%24 for i in range(s, e+1 if e >= s else 24+e+1)) type(hours) = generator ---- 顺便说一下,非常感谢。 - Anton vBR
1
是的,列表推导式和生成器推导式之间唯一的语法区别在于前者使用圆括号而不是方括号。与列表相比,生成器可以节省内存,因此你没有看到执行速度上的差异也就不足为奇了。 - SwiftsNamesake
显示剩余4条评论

1
你可以首先使用一种名为 modularRange 的函数生成你想要的数字。生成器表达式使代码更短;我们也可以使用一个 for 循环,结合 yield 来完成。
def modularRange(start, end, step, mod):
  return (i % mod for i in range(start, end + 1 + (0 if end >= start else mod), step))

你也可以在上限方面作弊,利用 bool 在核心上是 int 的事实:
range(start, end + 1 + mod*(end < start)

在您的情况下,mod参数将为24step1(小时)。
然后,您将使用np.array构造数组,就像其他帖子中所示。
np.array([datetime.time(hour,0) for hour in modularRange(start.hour, end.hour, 1, 24)])

OP请求一个含有分钟的例子。下面的代码将生成每5分钟间隔的datetime.time对象。我必须修改modularRange函数来考虑步长。

startMin = start.hour * 60 + start.minute # Convert to minutes
endMin   = end.hour   * 60 + end.minute   # Convert to minutes
np.array([datetime.time(mins//60, mins%60) for mins in modularRange(startMin, endMin, 5, 24*60)])

你没有问到分钟,但如果你需要一个例子,我可以编辑我的答案来涵盖它。 - SwiftsNamesake
@LorenzoBottaccioli 编辑 - SwiftsNamesake
@LorenzoBottaccioli,我的回答是否完整地回答了您的问题,或者您还有需要了解的其他内容吗? - SwiftsNamesake

0
datetime.time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> 获得一个时间对象
如果您想查看一些 datetime.time 的属性,例如:
start.hour
>>> 22    
end.hour
>>> 2
start.max
>>> datetime.time(23, 59, 59, 999999)
start.max.hour
>>> 23

您可以使用以上要素来实现您的list
[datetime.time(i, 0) for i in range(start.hour, start.max.hour+1)] + [datetime.time(i, 0) for i in range(end.min.hour, end.hour+1)]
Out[157]: [datetime.time(22, 0), datetime.time(23, 0), datetime.time(0, 0), datetime.time(1, 0), datetime.time(2, 0)]

您不必创建两个单独的列表。 - SwiftsNamesake

-1

更简单的解决方案可以是:

T = np.arange(datetime.date(2019, 4, 13),datetime.date(2020, 4, 13))

请阅读[答案]并[编辑]您的答案,以包含有关此代码实际解决问题的说明。请记住,您不仅要解决问题,还要教育OP和任何未来读者。 - Adriaan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接