user3826115 user3826115 - 14 days ago 7
Python Question

Put list of datetime objects spanning multiple days into 2-hourly bins

I have a list of datetime objects, with the date range spanning multiple years.

I would like to divide these dates into 2 hourly bins. So for the 0 hr bin, all of the datetimes from 23:00 - 1:00 would go in this bin (+/- 1 hr).

In the end I would like a list of the index of each datetime that falls within a bin. So if my datetime list was something like

datetime.datetime(2014, 10, 3, 20, 29, 54, 268074),
datetime.datetime(2014, 10, 4, 11, 28, 34, 59937),
datetime.datetime(2014, 10, 4, 19, 40, 39, 718856),
datetime.datetime(2016, 8, 18, 12, 17, 57, 417245),
datetime.datetime(2016, 8, 19, 1, 37, 57, 465573)


I want a result of a list of lists like:

[[],
[4],
[],
[],
[],
[],
[1,3],
[],
[],
[],
[0,2],
[]]


Where result[0] give me a list of indexes that correspond to datetimes closest to the 0:00, result[0] gives a list closest to 2:00, etc.

My first thought was to use the datetime.time object to create a list of hours, and then subtract a datetime from my list and find the minimum.

import datetime
hrs = array([datetime.time(t) for t in arange(0,24,2)])
closetHr = min(hrs - times[0].time())


But this gives me the error
unsupported operand type(s) for -: 'datetime.time' and 'datetime.time'

Answer

This produces the expected output for the sample input, avoiding the time subtraction:

bins = [[] for t in arange(0,24,2)]
for i,t in enumerate(times):
    ix = (t.hour+1)%24     # "normalize" the hour
    bins[ix/2].append( i ) # convert to a bin index

Not clear if this does what you want when the value is on an odd-hour boundary (i.e. 1:00), but then you didn't specify.

Comments