熊猫:使用工作日历检查日期是否为假期,并为英国和其他国家/地区的日历分配布尔值

时间:2019-08-08 00:41:07

标签: python pandas boolean

我有几个国家/地区的财务时间序列,对于每个时间序列,我都希望删除该特定国家/地区公共假期的观测值。为此,我在时间序列中创建一个带有布尔值的新列,以指示日期是否为假期。

因此,我发现此代码分配了布尔值,并且对我的美国时间序列非常有用: Pandas: Checking if a date is a holiday and assigning boolean value

但是我无法在其他国家/地区使用它。我尝试使用workalendar(例如以下代码),但收到错误消息。对于使用工作日历或其他方法的任何建议,我将不胜感激。

OnPostAsync
from datetime import date
from workalendar.europe import UnitedKingdom
cal = UnitedKingdom()

holidays = cal.holidays(start=uk_daily['Date for PH'].min(), 
                    end=uk_daily['Date for PH'].max()).to_pydatetime()
uk_daily['Holiday'] = uk_daily['Date for PH'].isin(holidays)

数据只是一个带有时间索引和几列的Pandas数据帧。使用以下可重现的示例,我得到了相同的错误消息:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-26-2d820caa4432> in <module>
      4 
      5 holidays = cal.holidays(start=uk_daily['Date for PH'].min(),
----> 6                         end=uk_daily['Date for PH'].max()).to_pydatetime()

TypeError: holidays() got an unexpected keyword argument 'start'

1 个答案:

答案 0 :(得分:0)

holidays的构造函数只用一年,例如cal.holidays(2019),而不是开始和结束年份。返回的值是一个元组对的列表,其中包含假日的datetime.date值及其各自的名称。

>>> cal.holidays(2019)
[(datetime.date(2019, 1, 1), 'New year'),
 (datetime.date(2019, 4, 19), 'Good Friday'),
 (datetime.date(2019, 4, 21), 'Easter Sunday'),
 (datetime.date(2019, 4, 22), 'Easter Monday'),
 (datetime.date(2019, 5, 6), 'Early May Bank Holiday'),
 (datetime.date(2019, 5, 27), 'Spring Bank Holiday'),
 (datetime.date(2019, 8, 26), 'Late Summer Bank Holiday'),
 (datetime.date(2019, 12, 25), 'Christmas Day'),
 (datetime.date(2019, 12, 26), 'Boxing Day')]

因此,您需要获取开始日期和结束日期之间的年份范围,然后使用条件集合理解条件在每年调用构造函数,条件是假日在开始日期和结束日期之间(包括两端)。我们采用每个元组对的第一个元素来获取假期日期(holiday[0])。

start = uk_daily['Date for PH'].min()
start_year = start.year  # Assuming dates are Timestamp objects.
end = uk_daily['Date for PH'].max()
end_year = end.year 

holidays = set(holiday[0] 
               for year in range(start_year, end_year + 1)
               for holiday in cal.holidays(year)
               if start.date() <= holiday[0] <= end.date())

我使用集合理解而不是列表理解,因为测试日期成员资格应该更快。

然后像以前一样测试成员资格:

uk_daily['Holiday'] = uk_daily['Date for PH'].isin(holidays)