【问题标题】:Pandas: Using workalendar to check if a date is a holiday and assigning boolean value for UK and other countries' calendarsPandas:使用 workalendar 检查日期是否为假期并为英国和其他国家的日历分配布尔值
【发布时间】:2019-08-08 00:41:07
【问题描述】:

我有几个国家/地区的财务时间序列,对于每个时间序列,我想删除落在该特定国家公共假期的观察结果。为此,我在时间序列中创建了一个新列,其中包含布尔值来指示日期是否为假日。

所以我找到了这段代码来分配布尔值,它非常适合我的美国时间序列: Pandas: Checking if a date is a holiday and assigning boolean value

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

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)
---------------------------------------------------------------------------
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'

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

import pandas as pd
from datetime import date
from workalendar.europe import UnitedKingdom
cal = UnitedKingdom()

dr = pd.date_range(start='1996-01-01', end='2019-06-28')
df = pd.DataFrame()
df['Date'] = dr

holidays = cal.holidays(start=dr.min(), end=dr.max()).to_pydatetime()
df['Holiday'] = df['Date'].isin(holidays)
df.head(10)

【问题讨论】:

  • 首先,您的代码基于问题而不是答案,其次,答案不是使用workalendar,而是使用熊猫数据集。如果您想使用 workalendar 数据,您需要将其转换为在 Pandas 中使用。
  • 感谢您指出这一点。我将如何转换工作日历数据?

标签: python pandas boolean


【解决方案1】:

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多