Checking for Custom Business Days with pandas: Beyond the Basics


Data Offsets in pandas

In pandas, data offsets are used to represent time intervals for date/time manipulations. They provide a convenient way to shift dates by specific durations, such as days, weeks, months, or years, while adhering to business day calendars or custom rules.

CustomBusinessDay: Defining Custom Business Days

The CustomBusinessDay class is a subclass of DateOffset that allows you to create custom business day offsets. It offers more flexibility than the standard business day offset (BDay) by enabling you to:

  • Use a custom calendar object for business day identification
  • Provide a list of holidays to treat as non-business days
  • Specify a custom weekmask (e.g., to exclude certain weekdays from business days)

is_on_offset Method

The is_on_offset method is a core component of CustomBusinessDay. Given a date/time (dt) as input, it returns a boolean value indicating whether dt falls on a business day according to the defined rules of the CustomBusinessDay object.

  1. Retrieving Custom Rules
    The method accesses the attributes of the CustomBusinessDay object to determine the custom weekmask, holidays, and calendar (if provided).
  2. Date Validation
    It checks if dt is a valid date/time object.
  3. Weekday Check
    Using the weekmask (defaults to Monday-Friday), is_on_offset verifies if the weekday of dt is included in the business days.
  4. Holiday Check
    It compares dt against the list of holidays (if provided) to see if it's a non-business day.
  5. Custom Calendar Check (Optional)
    If a custom calendar object is defined, the method delegates the business day determination to that calendar.
  6. Business Day Verdict
    Based on the above checks, is_on_offset returns True if dt is considered a business day according to the custom rules, and False otherwise.
import pandas as pd

# Define a CustomBusinessDay offset with a custom weekmask (Tuesday-Thursday)
custom_business_day = pd.offsets.CustomBusinessDay(weekmask='Tue Thu')

# Check if a specific date (e.g., July 4, 2024) is a business day according to the custom rules
date_to_check = pd.to_datetime('2024-07-04')
is_business_day = custom_business_day.is_on_offset(date_to_check)
print(is_business_day)  # Output: False (as July 4th is a Thursday, not Tuesday or Wednesday)


Checking for Business Days with Holidays

import pandas as pd

# Define a CustomBusinessDay offset with holidays and a custom weekmask
custom_business_day = pd.offsets.CustomBusinessDay(weekmask='Tue Thu', holidays=['2024-07-04'])

# Check if July 3, 2024 is a business day (Tuesday)
date_to_check = pd.to_datetime('2024-07-03')
is_business_day = custom_business_day.is_on_offset(date_to_check)
print(is_business_day)  # Output: True

# Check if July 4, 2024 (holiday) is a business day
date_to_check = pd.to_datetime('2024-07-04')
is_business_day = custom_business_day.is_on_offset(date_to_check)
print(is_business_day)  # Output: False

This example shows how you can define holidays and a custom weekmask. The code checks if July 3rd (Tuesday) is a business day according to the custom rules (True) and July 4th (a holiday) is not considered a business day (False).

Using a Custom Calendar (Advanced)

import pandas as pd

# Define a custom calendar class (replace with your specific logic)
class MyCustomCalendar:
    def is_business_day(self, date):
        # Implement your custom business day logic here
        # This could involve checking against a specific database or API
        if date.weekday() in [pd.TUESDAY, pd.THURSDAY]:
            return True
        else:
            return False

# Create a CustomBusinessDay offset using the custom calendar
custom_business_day = pd.offsets.CustomBusinessDay(calendar=MyCustomCalendar())

# Check if a date is a business day based on your custom calendar logic
date_to_check = pd.to_datetime('2024-07-05')  # Friday (not a business day by default)
is_business_day = custom_business_day.is_on_offset(date_to_check)

# Output depends on your custom calendar implementation (might be True)
print(is_business_day)

This example demonstrates how you can leverage a custom calendar class to define business days based on your own criteria. The provided code is a basic template, and you'll need to replace the MyCustomCalendar.is_business_day method with your specific logic for checking business days.



Using BDay with holidays parameter (Simpler Custom Business Days)

If you only need to define a custom business day offset with holidays, you can utilize the built-in BDay offset with the holidays parameter. It's simpler than CustomBusinessDay for this specific scenario:

import pandas as pd

# Define BDay offset with holidays
holidays = ['2024-07-04']  # Add your list of holidays
business_day_offset = pd.offsets.BDay(holidays=holidays)

# Check if a date falls on a business day considering holidays
date_to_check = pd.to_datetime('2024-07-03')
is_business_day = business_day_offset.is_on_offset(date_to_check)
print(is_business_day)  # Output: True

Vectorized Operations for Performance

If performance is critical and you're working with large datasets, consider vectorized operations instead of iterating through dates with is_on_offset. Here are two options:

  • Custom Vectorized Function: You can write a custom function using NumPy or pandas functions to perform vectorized checks for business days based on your criteria. This approach offers greater flexibility but requires more coding effort.

  • numpy.busdaycalendar: This function from NumPy allows you to create a calendar object representing business days based on a weekmask and holidays. You can then use vectorized operations to check if dates fall on business days.

External Business Day Calendars (Advanced)