5 Best Ways to Create a Custom BusinessHour Offset in Pandas

πŸ’‘ Problem Formulation: In time-sensitive data analysis, adjusting datetime indices by business hours is often required. Pandas provides a powerful set of tools for time series data, and one useful feature is the CustomBusinessHour offset object. This object allows for fine-tuning of working hours that deviate from the standard 9-to-5. For instance, you may want to align timestamp data to the next business closing time based on a 10-to-6 schedule.

Method 1: Basic CustomBusinessHour Offset

To create a basic CustomBusinessHour object in pandas, you can simply use the CustomBusinessHour class from the pandas.tseries.offsets module. This method is straightforward and ideal for creating a business hour offset with non-standard business hours.

Here’s an example:

from pandas.tseries.offsets import CustomBusinessHour
from datetime import datetime

# Define the custom business hours
custom_bhours = CustomBusinessHour(start='10:00', end='18:00')

# Create a datetime object
dt = datetime(2023, 1, 1, 11)

# Apply custom business hour offset
new_dt = dt + custom_bhours

print(new_dt)

Output:

2023-01-02 10:00:00

This code snippet creates a CustomBusinessHour object to represent business hours starting at 10 AM and ending at 6 PM. When applied to a datetime object representing 11 AM on January 1st, 2023, it calculates the next business hour, which is 10 AM on January 2nd, 2023, as January 1st is a non-business day.

Method 2: CustomBusinessHour with Weekmask

When dealing with business hours that don’t occur every weekday, you can create a CustomBusinessHour offset with a weekmask. This method allows definition of which days of the week are considered business days.

Here’s an example:

from pandas.tseries.offsets import CustomBusinessHour

# Define custom business hours with a weekmask
custom_bhours_weekmask = CustomBusinessHour(start='10:00', end='18:00', weekmask='Mon Tue Wed Thu')

# Apply custom business hour offset to a Friday
friday_date = '2023-01-06 15:30'
new_friday_date = pd.Timestamp(friday_date) + custom_bhours_weekmask

print(new_friday_date)

Output:

2023-01-09 10:00:00

This example demonstrates how to create a CustomBusinessHour offset that excludes Fridays. It increments a timestamp on a Friday by one business hour, which results in the next Monday at 10 AM, as Friday is not considered a business day.

Method 3: CustomBusinessHour with Holidays

Pandas also allows for incorporating holidays into the CustomBusinessHour calculation. By specifying a list of holidays, you can ensure that these days are skipped when calculating the next business hour.

Here’s an example:

from pandas.tseries.offsets import CustomBusinessHour
from pandas.tseries.holiday import USFederalHolidayCalendar

# Define the holidays
holidays = USFederalHolidayCalendar().holidays(start='2023-01-01', end='2023-12-31')

# Define custom business hours including holidays
custom_bhours_holidays = CustomBusinessHour(start='10:00', end='18:00', holidays=holidays)

# Apply custom business hour offset to a day before a holiday
date_before_holiday = '2023-07-03 16:00'
new_date = pd.Timestamp(date_before_holiday) + custom_bhours_holidays

print(new_date)

Output:

2023-07-05 10:00:00

This snippet accounts for US Federal Holidays when applying the CustomBusinessHour offset. For a timestamp on July 3rd at 4 PM, the adjustment skips July 4th, a holiday, resulting in the next business hour on July 5th at 10 AM.

Method 4: Combining Weekmask and Holidays

A more advanced method is to combine both a weekmask and holidays for creating a CustomBusinessHour object. This gives a high degree of customization for defining business hours.

Here’s an example:

from pandas.tseries.offsets import CustomBusinessHour
from pandas.tseries.holiday import USFederalHolidayCalendar

# Define both the holidays and the weekmask
holidays = USFederalHolidayCalendar().holidays(start='2023-01-01', end='2023-12-31')
weekmask = 'Mon Tue Wed Thu'

# Define custom business hours with both weekmask and holidays
custom_bhours_combined = CustomBusinessHour(start='10:00', end='18:00', weekmask=weekmask, holidays=holidays)

# Apply custom business hour offset to a date
date_combination = '2023-07-06 15:30'
new_date_combination = pd.Timestamp(date_combination) + custom_bhours_combined

print(new_date_combination)

Output:

2023-07-07 10:00:00

The code here uses both a weekmask excluding Fridays and US Federal Holidays when creating a CustomBusinessHour object. After moving forward one business hour from July 6th at 3:30 PM, it correctly rolls over to the next business day which is July 7th (Friday is included this time) at 10:00 AM.

Bonus One-Liner Method 5: Chaining Offsets

Sometimes you may want to quickly combine offsets without setting a full CustomBusinessHour. You can add a BusinessHour to a DateOffset directly.

Here’s an example:

import pandas as pd

# Create a one-liner offset by chaining
chained_offset = pd.offsets.BusinessHour() + pd.offsets.DateOffset(hours=2)

# Apply chained offset to a timestamp
timestamp = pd.Timestamp('2023-03-01 11:00')
new_timestamp = timestamp + chained_offset

print(new_timestamp)

Output:

2023-03-01 14:00:00

In this one-liner example, a standard BusinessHour offset is chained with a DateOffset of two hours. This adjusts a midday timestamp from 11 AM to 2 PM on the same business day.

Summary/Discussion

  • Method 1: Basic CustomBusinessHour. Great for simple non-standard business hours. Limited by not considering holidays or specific week days.
  • Method 2: CustomBusinessHour with Weekmask. Perfect for businesses that don’t operate on a standard Monday-to-Friday schedule. However, does not take into account holidays.
  • Method 3: CustomBusinessHour with Holidays. Ideal for incorporating public holidays into the offset calculation, but weekmask has to be defined separately.
  • Method 4: Combining Weekmask and Holidays. Offers high-level customization and accuracy in offset calculations. Can be complex to configure correctly.
  • Bonus Method 5: Chaining Offsets. Quick and straightforward, but lacks the customizability of CustomBusinessHour. Useful for minor adjustments.