如何在Pandas DataFrame中判断日期是否为工作日并生成下一个工作日列
Got it, let's break this down into manageable steps. We'll use pandas for dataframe handling and the holidays library to handle holiday checks (it supports most countries, so we'll use US holidays as an example since your dates follow US format).
1. First: Convert Date Strings to Datetime
Your date column is stored as plain text, so first we need to convert it to pandas datetime objects—this lets us use all the built-in date logic tools.
import pandas as pd import holidays # Your original dataframe data = {'date': ['11/4/17', '11/8/17', '11/16/17', '11/17/17', '11/19/17', '11/22/17', '11/23/17']} df = pd.DataFrame(data) # Convert to datetime (format is month/day/2-digit year) df['date'] = pd.to_datetime(df['date'], format='%m/%d/%y')
2. Flag Weekdays vs Weekends
We can use dt.weekday where 0=Monday, 4=Friday (so weekdays are values <5). Let's add columns to mark this and label the day type.
# Flag if the date is a weekday (Mon-Fri) df['is_weekday'] = df['date'].dt.weekday < 5 # Create a column to label day type (initially Weekday/Weekend) df['day_type'] = df['is_weekday'].map({True: 'Weekday', False: 'Weekend'})
3. Add Holiday Detection
Next, we'll check if dates are official holidays. The holidays library makes this easy—we'll use US holidays here, but you can swap in your country's code (e.g., holidays.CN() for China, holidays.UK() for UK).
# Create a US holiday object (covers federal holidays) us_holidays = holidays.US() # Flag if the date is a holiday df['is_holiday'] = df['date'].apply(lambda x: x in us_holidays) # Update day_type to mark holidays (overrides weekday flag if needed) df.loc[df['is_holiday'], 'day_type'] = 'Holiday'
4. Calculate the Next Valid Workday
Now we need a function that takes a date and returns the next day that's neither a weekend nor a holiday. We'll loop forward until we hit a valid workday.
def get_next_workday(date, holiday_list): next_day = date + pd.Timedelta(days=1) # Keep moving forward until we find a weekday that's not a holiday while next_day.weekday() >= 5 or next_day in holiday_list: next_day += pd.Timedelta(days=1) return next_day # Apply the function: use original date if it's a valid workday, else get next workday df['adjusted_date'] = df.apply( lambda row: row['date'] if row['is_weekday'] and not row['is_holiday'] else get_next_workday(row['date'], us_holidays), axis=1 )
Final Result
After running all this, your dataframe will look like this (dates in datetime format):
| index | date | is_weekday | day_type | is_holiday | adjusted_date |
|---|---|---|---|---|---|
| 0 | 2017-11-04 | False | Weekend | False | 2017-11-06 |
| 1 | 2017-11-08 | True | Weekday | False | 2017-11-08 |
| 2 | 2017-11-16 | True | Weekday | False | 2017-11-16 |
| 3 | 2017-11-17 | True | Weekday | False | 2017-11-17 |
| 4 | 2017-11-19 | False | Weekend | False | 2017-11-20 |
| 5 | 2017-11-22 | True | Weekday | False | 2017-11-22 |
| 6 | 2017-11-23 | True | Holiday | True | 2017-11-24 |
A quick note: 2017-11-23 is Thanksgiving (US federal holiday), so it gets adjusted to the next weekday (11/24, Friday).
Customization Tips
- If you need holidays for a different country, swap
holidays.US()with the appropriate code (check theholidayslibrary docs for supported regions). - If you have custom holidays (like company-specific days off), you can add them to the holiday list:
us_holidays.append(pd.to_datetime('2017-12-22'))
内容的提问来源于stack exchange,提问作者michael0196

