如何解决将工作日添加到带有日期的 Pandas 数据框并跳过假期 python
我有一个带有日期的数据框,如下表所示。第一个块是它应该是什么样子,第二个块是我在添加 BDays 时得到的。这是完成后的外观示例。我想使用第 1 列并为日期添加 5 个工作日,但如果 5 个工作日与假期重叠(例如 21 年 2 月 15 日),那么我需要再添加一天。使用 pandas.tseries.offsets import BDay
添加 5Bday 相当简单,但在使用数据框时我无法跳过假期。
我曾尝试使用 pandas.tseries.holiday import USFederalHolidayCalendar
、工作日和工作日历模块,但无法弄清楚。任何人都知道我能做什么。
正确的例子
日期 | 退出日期 +5 |
---|---|
2021/02/09 | 2021/02/17 |
2021/02/10 | 2021/02/18 |
错误示例
日期 | 退出日期 +5 |
---|---|
2021/02/09 | 2021/02/16 |
2021/02/10 | 2021/02/17 |
以下是我尝试过的一些代码示例:
import pandas as pd
from workdays import workday
...
df['DATE'] = workday(df['EXIT DATE +5'],days=5,holidays=holidays)
下一个例子:
import pandas as pd
from pandas.tseries.holiday import USFederalHolidayCalendar
bday_us = pd.offsets.CustomBusinessDay(calendar=USFederalHolidayCalendar())
dt = df['DATE']
df['EXIT DATE +5'] = dt + bday_us
解决方法
输入数据
df = pd.DataFrame(['2021-02-09','2021-02-10','2021-06-28','2021-06-29','2021-07-02'],columns=['DATE'])
df['DATE'] = pd.to_datetime(df['DATE'])
使用 apply 的建议解决方案
from pandas.tseries.holiday import USFederalHolidayCalendar
from pandas.tseries.offsets import BDay
def offset_date(start,offset):
return start + pd.offsets.CustomBusinessDay(n=offset,calendar=USFederalHolidayCalendar())
offset = 5
df['END'] = df.apply(lambda x: offset_date(x['DATE'],offset),axis=1)
DATE END
2021-02-09 2021-02-17
2021-02-10 2021-02-18
2021-06-28 2021-07-06
2021-06-29 2021-07-07
2021-07-02 2021-07-12
PS:如果您想使用特定日历(例如 NYSE),而不是默认的 USFederalHolidayCalendar
,我建议您按照 this answer 上的说明进行操作,以创建自定义日历。
我不推荐的替代解决方案
目前,据我所知,pandas 不支持矢量化方法来解决您的问题。但是,如果您想采用与您提到的方法类似的方法,那么您应该这样做。
首先,您必须定义一个任意遥远的 end
日期,其中包括您可能需要的所有时间段,并使用它来创建假期列表。
holidays = USFederalHolidayCalendar().holidays(start='2021-02-09',end='2030-02-09')
然后,您通过 holidays
参数而不是 holidays
将 calendar
列表传递给 CustomBusinessDay 以生成所需的偏移量。
offset = 5
bday_us = pd.offsets.CustomBusinessDay(n=offset,holidays=holidays)
df['END'] = df['DATE'] + bday_us
然而,这种方法并不是真正的矢量化解决方案,即使它看起来像。请参阅以下 SO answer 以获得进一步说明。在幕后,这种方法可能正在执行效率不高的转换。这就是为什么它会产生以下警告。
PerformanceWarning:非矢量化 DateOffset 应用于系列 或日期时间索引
,这是一种方法
import pandas as pd
from pandas.tseries.holiday import USFederalHolidayCalendar
from datetime import timedelta as td
def get_exit_date(date):
holiday_list = cals.holidays(start=date,end=date + td(weeks=2)).tolist()
# 6 periods since start date is included in set
n_bdays = pd.bdate_range(start=date,periods=6,freq='C',holidays=holiday_list)
return n_bdays[-1]
df = pd.read_clipboard()
cals = USFederalHolidayCalendar()
# I would convert this to datetime
df['DATE'] = pd.to_datetime(df['DATE'])
df['EXIT DATE +5'] = df['DATE'].apply(get_exit_date)
这是使用返回日期时间索引的 bdate_range
结果:
DATE EXIT DATE +5
0 2021-02-09 2021-02-17
1 2021-02-10 2021-02-18
另一个选项是动态创建假期列表。您也可以选择一个开始日期并将其保留在函数之外,如下所示:
def get_exit_date(date):
# 6 periods since start date is included in set
n_bdays = pd.bdate_range(start=date,holidays=holiday_list)
return n_bdays[-1]
df = pd.read_clipboard()
cals = USFederalHolidayCalendar()
holiday_list = cals.holidays(start='2021-01-01').tolist()
# I would convert this to datetime
df['DATE'] = pd.to_datetime(df['DATE'])
df['EXIT DATE +5'] = df['DATE'].apply(get_exit_date)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。