将工作日添加到带有日期的 Pandas 数据框并跳过假期 python

如何解决将工作日添加到带有日期的 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 参数而不是 holidayscalendar 列表传递给 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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?