Working with Non-Standard Business Hours in Pandas Data Analysis


CustomBusinessHour Offset

The CustomBusinessHour offset in Pandas is a versatile tool for working with date and time data, specifically when you need to represent non-standard business hours or account for holidays. It allows you to define your own custom business day schedule within a Pandas Series or DataFrame.

Key Parameters

  • offsettimedelta: This optional parameter allows you to apply an additional time offset after applying the business hour logic. It's specified as a timedelta object (e.g., timedelta(hours=1) for adding an hour).
  • holidays: This optional parameter is a list of date objects (e.g., [datetime.datetime(2024, 7, 4)]) or strings representing holidays that should be considered non-business days.
  • weekmask: This optional parameter is a string containing a series of "D" (business day) or "N" (non-business day) characters, representing the days of the week according to your custom schedule. By default, it assumes Monday to Friday are business days ("D" for those days, "N" for weekends).
  • end: This parameter defines the end time of your business day in 24-hour format (e.g., "17:00" for 5 PM).
  • start: This parameter specifies the start time of your business day in 24-hour format (e.g., "09:00" for 9 AM).

n Attribute

Common Usages

Here are some common scenarios where you might use CustomBusinessHour:

  • Defining custom weekend behavior (e.g., if your business operates on Saturdays).
  • Accounting for holidays or specific non-working days within your data.
  • Representing a business day that starts earlier or later than the standard 9 AM to 5 PM schedule.

Example

import pandas as pd

# Custom business hours: 8 AM to 4 PM, weekdays only (no weekends)
custom_hours = pd.offsets.CustomBusinessHour(start="08:00", end="16:00")

# Create a pandas Series with a starting date
dates = pd.date_range(start="2024-06-28", periods=5)  # Today is June 29, 2024

# Offset the dates by 2 business days using the custom business hour offset
offset_dates = dates + 2 * custom_hours

print(offset_dates)

This code will output the following dates, skipping Saturday and Sunday:

0    2024-07-02
1    2024-07-03
2    2024-07-04
3    2024-07-05
4    2024-07-08
dtype: datetime64[ns]


Example 1: Weekends as Business Days

This code defines a custom business hour where Saturdays are also considered business days:

import pandas as pd

# Weekends included as business days (Sat = 'D', Sun = 'N')
weekend_business_hours = pd.offsets.CustomBusinessHour(weekmask="Mon Tue Wed Thu Fri Sat N")

# Create a pandas Series with a starting date
dates = pd.date_range(start="2024-06-29", periods=5)

# Offset the dates by 3 business days (including Saturdays)
offset_dates = dates + 3 * weekend_business_hours

print(offset_dates)

This will output:

0    2024-06-29
1    2024-07-01
2    2024-07-02
3    2024-07-06
4    2024-07-08
dtype: datetime64[ns]

Example 2: Adding an Offset After Business Hours

This code demonstrates using offsettimedelta to add an additional hour after applying the business hour logic:

import pandas as pd

# Standard business hours with 1-hour offset
standard_hours = pd.offsets.CustomBusinessHour(offsettimedelta=pd.Timedelta(hours=1))

# Create a pandas Series with a starting date
dates = pd.date_range(start="2024-06-28", periods=2)

# Offset the dates by 1 business day with 1-hour post-offset
offset_dates = dates + standard_hours

print(offset_dates)
0    2024-06-28 17:00:00
1    2024-07-02 09:00:00
dtype: datetime64[ns]

Example 3: Including Holidays

This code defines a custom business hour while considering a specific holiday:

import pandas as pd

from datetime import datetime

# Standard business hours with July 4th as a holiday
standard_hours = pd.offsets.CustomBusinessHour(holidays=[datetime(2024, 7, 4)])

# Create a pandas Series with a starting date (including July 4th)
dates = pd.date_range(start="2024-07-01", periods=4)

# Offset the dates by 2 business days, skipping July 4th
offset_dates = dates + 2 * standard_hours

print(offset_dates)
0    2024-07-01
1    2024-07-03
2    2024-07-05
3    2024-07-08
dtype: datetime64[ns]


Combining CustomBusinessHour with multiplication

  • You can leverage multiplication with the CustomBusinessHour offset object to achieve a similar effect as potentially envisioned for n. For example:
import pandas as pd

# Standard business hours
standard_hours = pd.offsets.CustomBusinessHour()

# Offset by 3 business days (equivalent to n=3)
offset_dates = starting_date + 3 * standard_hours

Utilizing BDay offset with weekmask and holidays

  • The BDay offset represents a business day and allows you to specify a custom weekmask (similar to weekmask in CustomBusinessHour) and holidays using the holidays parameter.
import pandas as pd

from pandas.tseries.offsets import BDay

# Weekends as non-business days (Mon-Fri)
weekend_mask = "Mon Tue Wed Thu Fri"

# Offset by 2 business days (excluding weekends)
offset_dates = starting_date + 2 * BDay(weekmask=weekend_mask)

# Alternatively, include holidays as well
holidays = [datetime(2024, 7, 4)]  # Add your holidays here
offset_dates = starting_date + 2 * BDay(weekmask=weekend_mask, holidays=holidays)
  • If you need more granular control or calculations involving time intervals, you can write custom logic using the timedelta object.
import pandas as pd
from datetime import timedelta

# Standard business hours (9 AM to 5 PM)
business_hours = timedelta(hours=8)  # Adjust for your business hours

# Function to add N business days (excluding weekends)
def add_business_days(date, n):
  for _ in range(n):
    date += timedelta(days=1)
    while date.weekday() > 4:  # Check for weekends (Saturday & Sunday)
      date += timedelta(days=1)
  return date

# Offset by 2 business days
offset_dates = add_business_days(starting_date, 2)