Reputation: 441
How can I generate an array of datetime.time
objects from these two objects:
start = datetime.time(22, 0)
end = datetime.time( 2, 0)
That will look like:
interval = array([datetime.time(22,0), datetime.time(23,0), datetime.time(0,0),
datetime.time( 1,0), datetime.time( 2,0)])
EDIT
In this example the delta is hour=1, but it might be minutes or seconds. I'm loking for something similar to pandas.date_range
.
Upvotes: 3
Views: 11050
Reputation: 1
More simplistic solution can be
T = np.arange(datetime.date(2019, 4, 13),datetime.date(2020, 4, 13))
Upvotes: -1
Reputation: 1578
You could first generate the numbers you want with a kind of modularRange
function. The generator expression makes the code shorter; we could've used a for
loop, coupled with yield
.
def modularRange(start, end, step, mod):
return (i % mod for i in range(start, end + 1 + (0 if end >= start else mod), step))
You could also cheat a bit with the upper bound, exploiting the fact that bool
s are int
s at the core:
range(start, end + 1 + mod*(end < start)
The mod
argument would be 24
in your case and step
is 1
(hour).
You'd then use np.array
to construct the array, as the other posters have shown.
np.array([datetime.time(hour,0) for hour in modularRange(start.hour, end.hour, 1, 24)])
The OP requested an example with minutes. The code below will generate datetime.time
objects at 5-minute intervals. I had to amend the modularRange
function to account for steps.
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)])
Upvotes: 1
Reputation: 18916
update shorter version with 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 loops, best of 3: 12.6 µs per loop
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 loops, best of 3: 79.9 µs per loop
update2 Using mod thanks to SwiftsNamesake, this can be solved in a single list comprehension
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 loops, best of 3: 3.75 µs per loop
Upvotes: 1
Reputation: 5061
datetime.time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object
So if you look out some attributes
of datetime.time
like
start.hour
>>> 22
end.hour
>>> 2
start.max
>>> datetime.time(23, 59, 59, 999999)
start.max.hour
>>> 23
You can implement your list
using above factor.
[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)]
Upvotes: 0