I am using following if loop for creating half an hourly buckets for approx 1 million observations which is taking hell lot of time. Following is my if loop
def half_hourly_buckets(dataframe,time_column):
dataframe[time_column] = pd.to_datetime(dataframe[time_column],format = '%H:%M:%S').dt.time
for j in range(len(dataframe)):
x = dataframe.loc[j,time_column]
if (x >= datetime.time(0,0,1)) & (x <= datetime.time(0,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "00:00:01 - 00:30:00"
elif (x >= datetime.time(0,30,1)) & (x <= datetime.time(1,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "00:30:01 - 01:00:00"
elif (x >= datetime.time(1,0,1)) & (x <= datetime.time(1,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "01:00:01 - 01:30:00"
elif (x >= datetime.time(1,30,1)) & (x <= datetime.time(2,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "01:30:01 - 02:00:00"
elif (x >= datetime.time(2,0,1)) & (x <= datetime.time(2,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "02:00:01 - 02:30:00"
elif (x >= datetime.time(2,30,1)) & (x <= datetime.time(3,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "02:30:01 - 03:00:00"
elif (x >= datetime.time(3,0,1)) & (x <= datetime.time(3,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "03:00:01 - 03:30:00"
elif (x >= datetime.time(3,30,1)) & (x <= datetime.time(4,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "03:30:01 - 04:00:00"
elif (x >= datetime.time(4,0,1)) & (x <= datetime.time(4,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "04:00:01 - 04:30:00"
elif (x >= datetime.time(4,30,1)) & (x <= datetime.time(5,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "04:30:01 - 05:00:00"
elif (x >= datetime.time(5,0,1)) & (x <= datetime.time(5,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "05:00:01 - 05:30:00"
elif (x >= datetime.time(5,30,1)) & (x <= datetime.time(6,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "05:30:01 - 06:00:00"
elif (x >= datetime.time(6,0,1)) & (x <= datetime.time(6,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "06:00:01 - 06:30:00"
elif (x >= datetime.time(6,30,1)) & (x <= datetime.time(7,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "06:30:01 - 07:00:00"
elif (x >= datetime.time(7,0,1)) & (x <= datetime.time(7,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "07:00:01 - 07:30:00"
elif (x >= datetime.time(7,30,1)) & (x <= datetime.time(8,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "07:30:01 - 08:00:00"
elif (x >= datetime.time(8,0,1)) & (x <= datetime.time(8,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "08:00:01 - 08:30:00"
elif (x >= datetime.time(8,30,1)) & (x <= datetime.time(9,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "08:30:01 - 09:00:00"
elif (x >= datetime.time(9,0,1)) & (x <= datetime.time(9,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "09:00:01 - 09:30:00"
elif (x >= datetime.time(9,30,1)) & (x <= datetime.time(10,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "09:30:01 - 10:00:00"
elif (x >= datetime.time(10,0,1)) & (x <= datetime.time(10,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "10:00:01 - 10:30:00"
elif (x >= datetime.time(10,30,1)) & (x <= datetime.time(11,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "10:30:01 - 11:00:00"
elif (x >= datetime.time(11,0,1)) & (x <= datetime.time(11,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "11:00:01 - 11:30:00"
elif (x >= datetime.time(11,30,1)) & (x <= datetime.time(12,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "11:30:01 - 12:00:00"
elif (x >= datetime.time(12,0,1)) & (x <= datetime.time(12,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "12:00:01 - 12:30:00"
elif (x >= datetime.time(12,30,1)) & (x <= datetime.time(13,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "12:30:01 - 13:00:00"
elif (x >= datetime.time(13,0,1)) & (x <= datetime.time(13,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "13:00:01 - 13:30:00"
elif (x >= datetime.time(13,30,1)) & (x <= datetime.time(14,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "13:30:01 - 14:00:00"
elif (x >= datetime.time(14,0,1)) & (x <= datetime.time(14,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "14:00:01 - 14:30:00"
elif (x >= datetime.time(14,30,1)) & (x <= datetime.time(15,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "14:30:01 - 15:00:00"
elif (x >= datetime.time(15,0,1)) & (x <= datetime.time(15,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "15:00:01 - 15:30:00"
elif (x >= datetime.time(15,30,1)) & (x <= datetime.time(16,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "15:30:01 - 16:00:00"
elif (x >= datetime.time(16,0,1)) & (x <= datetime.time(16,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "16:00:01 - 16:30:00"
elif (x >= datetime.time(16,30,1)) & (x <= datetime.time(17,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "16:30:01 - 17:00:00"
elif (x >= datetime.time(17,0,1)) & (x <= datetime.time(17,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "17:00:01 - 17:30:00"
elif (x >= datetime.time(17,30,1)) & (x <= datetime.time(18,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "17:30:01 - 18:00:00"
elif (x >= datetime.time(18,0,1)) & (x <= datetime.time(18,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "18:00:01 - 18:30:00"
elif (x >= datetime.time(18,30,1)) & (x <= datetime.time(19,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "18:30:01 - 19:00:00"
elif (x >= datetime.time(19,0,1)) & (x <= datetime.time(19,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "19:00:01 - 19:30:00"
elif (x >= datetime.time(19,30,1)) & (x <= datetime.time(20,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "19:30:01 - 20:00:00"
elif (x >= datetime.time(20,0,1)) & (x <= datetime.time(20,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "20:00:01 - 20:30:00"
elif (x >= datetime.time(20,30,1)) & (x <= datetime.time(21,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "20:30:01 - 21:00:00"
elif (x >= datetime.time(21,0,1)) & (x <= datetime.time(21,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "21:00:01 - 21:30:00"
elif (x >= datetime.time(21,30,1)) & (x <= datetime.time(22,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "21:30:01 - 22:00:00"
elif (x >= datetime.time(22,0,1)) & (x <= datetime.time(22,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "22:00:01 - 22:30:00"
elif (x >= datetime.time(22,30,1)) & (x <= datetime.time(23,0,0)):
dataframe.loc[j,'half_hourly_bucket'] = "22:30:01 - 23:00:00"
elif (x >= datetime.time(23,0,1)) & (x <= datetime.time(23,30,0)):
dataframe.loc[j,'half_hourly_bucket'] = "23:00:01 - 23:30:00"
else:
dataframe.loc[j,'half_hourly_bucket'] = "23:30:01 - 00:00:00"
return dataframe
Is there any way to avoid this loop and increase the processing speed?
Firstly, you're doing about twice the number of comparisons you need for this approach. If you don't pass the first test, you already know that
x >= datetime.time(0,30,1))
so you don't have to test this a second time on the next elif.
Secondly, because of the regular buckets you're using, you can work out which bucket you need by taking the number of seconds and using the integer part of the result of dividing that by thirty minutes. Assuming x is a time object you could do something like this:
bucket_number = int((datetime.datetime.combine(datetime.date.min, x) -
datetime.datetime.combine(datetime.date.min, datetime.time(0))
).total_seconds() / (30 * 60))
bucket_start = datetime.datetime.combine(datetime.date.min, datetime.time(0)) + \
datetime.timedelta(seconds = bucket_number * 30 * 60)
bucket_end = datetime.datetime.combine(datetime.date.min, datetime.time(0)) + \
datetime.timedelta(seconds = (bucket_number + 1) * 30 * 60)
dataframe.loc[j,'half_hourly_bucket'] = "{} - {}".format(bucket_start.strftime('%H:%M:%S'),
bucket_end.strftime('%H:%M:%S'))
This will remove the need for any tests.
Note: A lot of the hard work here is because it's difficult to work with time objects. If you could use datetime objects instead, this would be a whole lot easier.
You could take a different approach and use timedelta to define the bucket, which severely simplifies this code:
from datetime import datetime, timedelta
def ceil_dt(dt, delta):
return dt + (datetime.min - dt) % delta
def floor_dt(dt, delta):
return dt - (dt - datetime.min) % delta
now = datetime.now()
print(now)
print(
floor_dt(now, timedelta(minutes=30)), ceil_dt(now, timedelta(minutes=30))
)
https://repl.it/@ryanpcmcquen/TwinHelplessLifecycles-1
floor_dt gives you the beginning of the bucket and ceil_dt gives you the end of it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With