看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
由于不同地区不同文化,工作、营业时间不尽相同。在数据分析时需要考虑是否是工作日、礼拜日等文化差异带来的影响。比如,埃及的周末是星期五和星期六。
Cday
或 CustomBusinessDay
类可以传入节假日参数来自定义一个工作日偏移对象:
weekmask_egypt = 'Sun Mon Tue Wed Thu'
# 定义出五一劳动节的日期,因为放假
holidays = ['2012-05-01',
datetime.datetime(2013, 5, 1),
np.datetime64('2014-05-01')]
# 自定义工作日中传入休假日期,一个正常星期工作日的顺序
bday_egypt = pd.offsets.CustomBusinessDay(holidays=holidays,
weekmask=weekmask_egypt)
# 指定一个日期
dt = datetime.datetime(2013, 4, 30)
# 偏移两个工作日,跳过了五一个休假日
dt + 2 * bday_egypt
# Timestamp('2013-05-05 00:00:00')
可以将日期的具体星期匹配映射出来:
dts = pd.date_range(dt, periods=5, freq=bday_egypt)
(pd.Series(dts.weekday, dts)
.map(pd.Series('Mon Tue Wed Thu Fri Sat Sun'.split()
)
)
)
'''
2013-04-30 Tue
2013-05-02 Thu
2013-05-05 Sun
2013-05-06 Mon
2013-05-07 Tue
Freq: C, dtype: object
'''
Pandas 内置了一些常用的节假日日历:
# 美国佛罗里达州的节假日
from pandas.tseries.holiday import USFederalHolidayCalendar
bday_us = pd.offsets.CustomBusinessDay(calendar=USFederalHolidayCalendar())
# 马丁路德金纪念日前是周五
dt = datetime.datetime(2014, 1, 17)
# 马丁路德金纪念日后为周二,周一放假,跳过
dt + bday_us
# Timestamp('2014-01-21 00:00:00')
可以在时序数据频率中使用:
bmth_us = pd.offsets.CustomBusinessMonthBegin(calendar=USFederalHolidayCalendar())
dt = datetime.datetime(2013, 12, 17)
# 跳过元旦
dt + bmth_us
# Timestamp('2014-01-02 00:00:00')
# 频率中应用自定义工作偏移
pd.date_range(start='20100101', end='20120101', freq=bmth_us)
'''
DatetimeIndex(['2010-01-04', '2010-02-01', '2010-03-01', '2010-04-01',
'2010-05-03', '2010-06-01', '2010-07-01', '2010-08-02',
'2010-09-01', '2010-10-01', '2010-11-01', '2010-12-01',
'2011-01-03', '2011-02-01', '2011-03-01', '2011-04-01',
'2011-05-02', '2011-06-01', '2011-07-01', '2011-08-01',
'2011-09-01', '2011-10-03', '2011-11-01', '2011-12-01'],
dtype='datetime64[ns]', freq='CBMS')
'''
注:频率字符串“ C”用于表示已使用 CustomBusinessDay DateOffset,由于CustomBusinessDay 是参数化类型,因此 CustomBusinessDay 的实例可能会有所不同,并且无法从 “ C” 频率字符串中检测到。 因此,需要确保在用户的应用程序中始终使用“ C”频率字符串。
BusinessHour
表是开始和结束工作的小时时间,默认的工作时间是 9:00 - 17:00,与时间相加超过一个小时会移到下一个小时,超过一天会移动到下一个工作日。
bh = pd.offsets.BusinessHour()
bh
# <BusinessHour: BH=09:00-17:00>
# 2014-08-01 是周五
pd.Timestamp('2014-08-01 10:00').weekday()
# 4
# 增加一个工作小时
pd.Timestamp('2014-08-01 10:00') + bh
# Timestamp('2014-08-01 11:00:00')
# 一但计算就等于上班了,等同于 pd.Timestamp('2014-08-01 09:00') + bh
pd.Timestamp('2014-08-01 08:00') + bh
# Timestamp('2014-08-01 10:00:00')
# 计算后已经下班了,就移到下一个工作小时(跳过周末)
pd.Timestamp('2014-08-01 16:00') + bh
Out[205]: Timestamp('2014-08-04 09:00:00')
# 同上逻辑,移动一个工作小时
pd.Timestamp('2014-08-01 16:30') + bh
Out[206]: Timestamp('2014-08-04 09:30:00')
# 偏移两个工作小时
pd.Timestamp('2014-08-01 10:00') + pd.offsets.BusinessHour(2)
# Timestamp('2014-08-01 12:00:00')
# 减去3个工作小时
pd.Timestamp('2014-08-01 10:00') + pd.offsets.BusinessHour(-3)
# Timestamp('2014-07-31 15:00:00')
可以自己定义开始和结束工作的时间,格式必须是 hour:minute
字符串,不支持秒、微秒、纳秒,会报错,因为工作时间没有定这么细的,可能。
# 11点开始上班
bh = pd.offsets.BusinessHour(start='11:00', end=datetime.time(20, 0))
bh
# <BusinessHour: BH=11:00-20:00>
pd.Timestamp('2014-08-01 13:00') + bh
# Timestamp('2014-08-01 14:00:00')
pd.Timestamp('2014-08-01 09:00') + bh
# Timestamp('2014-08-01 12:00:00')
pd.Timestamp('2014-08-01 18:00') + bh
# Timestamp('2014-08-01 19:00:00')
start 时间晚于 end 时间表示夜班工作时间。此时,工作时间将从午夜延至第二天。
bh = pd.offsets.BusinessHour(start='17:00', end='09:00')
bh
# <BusinessHour: BH=17:00-09:00>
pd.Timestamp('2014-08-01 17:00') + bh
# Timestamp('2014-08-01 18:00:00')
pd.Timestamp('2014-08-01 23:00') + bh
# Timestamp('2014-08-02 00:00:00')
# 尽管 2014 年 8 月 2 日是周六,
# 但因为工作时间周五开始,因此也有效
pd.Timestamp('2014-08-02 04:00') + bh
# Timestamp('2014-08-02 05:00:00')
# 虽然 2014 年 8 月 4 日是周一,
# 但开始时间是周日,超出了工作时间
pd.Timestamp('2014-08-04 04:00') + bh
# Timestamp('2014-08-04 18:00:00')
CustomBusinessHour
是 BusinessHour
和 CustomBusinessDay
的混合体,可以指定任意节假日。 CustomBusinessHour
与 BusinessHour
的工作原理相同,只是它跳过指定的自定义假日。
from pandas.tseries.holiday import USFederalHolidayCalendar
bhour_us = pd.offsets.CustomBusinessHour(calendar=USFederalHolidayCalendar())
# 马丁路德金纪念日之前的周五
dt = datetime.datetime(2014, 1, 17, 15)
dt + bhour_us
Timestamp('2014-01-17 16:00:00')
# 跳至马丁路德金纪念日之后的周二,周一放假,跳过
In [229]: dt + bhour_us * 2
Out[229]: Timestamp('2014-01-21 09:00:00')
您可以使用 BusinessHour
和 CustomBusinessDay
支持的关键字参数。
bhour_mon = pd.offsets.CustomBusinessHour(start='10:00',
weekmask='Tue Wed Thu Fri')
# 周一是节日,跳过,工作时间从 10 点开始
dt + bhour_mon * 2
Timestamp('2014-01-21 10:00:00')
更新时间:2020-06-11 16:31:20 标签:pandas 工作日