Получайте рабочие дни между датой начала и окончания, используя pandas
Я использую pandas, и мне интересно, какой простой способ получить рабочие дни между датой начала и окончания с помощью pandas?
Есть много сообщений о том, как это сделать в Python (для пример), но мне было бы интересно использовать непосредственно pandas, поскольку я думаю, что pandas, возможно, справится с этим довольно легко.
Ответы
Ответ 1
Используйте BDay()
, чтобы получить рабочие дни в диапазоне.
from pandas.tseries.offsets import *
In [185]: s
Out[185]:
2011-01-01 -0.011629
2011-01-02 -0.089666
2011-01-03 -1.314430
2011-01-04 -1.867307
2011-01-05 0.779609
2011-01-06 0.588950
2011-01-07 -2.505803
2011-01-08 0.800262
2011-01-09 0.376406
2011-01-10 -0.469988
Freq: D
In [186]: s.asfreq(BDay())
Out[186]:
2011-01-03 -1.314430
2011-01-04 -1.867307
2011-01-05 0.779609
2011-01-06 0.588950
2011-01-07 -2.505803
2011-01-10 -0.469988
Freq: B
С нарезкой:
In [187]: x=datetime(2011, 1, 5)
In [188]: y=datetime(2011, 1, 9)
In [189]: s.ix[x:y]
Out[189]:
2011-01-05 0.779609
2011-01-06 0.588950
2011-01-07 -2.505803
2011-01-08 0.800262
2011-01-09 0.376406
Freq: D
In [190]: s.ix[x:y].asfreq(BDay())
Out[190]:
2011-01-05 0.779609
2011-01-06 0.588950
2011-01-07 -2.505803
Freq: B
и count()
In [191]: s.ix[x:y].asfreq(BDay()).count()
Out[191]: 3
Ответ 2
Вы также можете использовать date_range
для этой цели.
In [3]: pd.date_range('2011-01-05', '2011-01-09', freq=BDay())
Out[3]: DatetimeIndex(['2011-01-05', '2011-01-06', '2011-01-07'], dtype='datetime64[ns]', freq='B', tz=None)
ИЗМЕНИТЬ
Или даже более простой
In [7]: pd.bdate_range('2011-01-05', '2011-01-09')
Out[7]: DatetimeIndex(['2011-01-05', '2011-01-06', '2011-01-07'], dtype='datetime64[ns]', freq='B', tz=None)
Обратите внимание, что даты начала и окончания включены.
Источник: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.bdate_range.html
Ответ 3
Начиная с v0.14 вы можете использовать праздничные календари.
from pandas.tseries.holiday import USFederalHolidayCalendar
from pandas.tseries.offsets import CustomBusinessDay
us_bd = CustomBusinessDay(calendar=USFederalHolidayCalendar())
print pd.DatetimeIndex(start='2010-01-01',end='2010-01-15', freq=us_bd)
возвращает:
DatetimeIndex(['2010-01-04', '2010-01-05', '2010-01-06', '2010-01-07',
'2010-01-08', '2010-01-11', '2010-01-12', '2010-01-13',
'2010-01-14', '2010-01-15'],
dtype='datetime64[ns]', freq='C')
Ответ 4
Просто будьте осторожны при использовании bdate_range или BDay() - имя может ввести вас в заблуждение, чтобы подумать, что это целый ряд рабочих дней, тогда как на самом деле это просто календарные дни с выходными в выходные дни (т.е.).
Ответ 5
Поверх этого ответа мы можем написать короткую функцию для возврата торговых дней биржи США:
def business_dates(start, end):
us_cal = USTradingCalendar()
kw = dict(start=start, end=end)
return pd.DatetimeIndex(freq='B', **kw).drop(us_cal.holidays(**kw))
In[1]: business_dates(start='2018-12-20', end='2018-12-31')
Out[1]: DatetimeIndex(['2018-12-20', '2018-12-21', '2018-12-24', '2018-12-26',
'2018-12-27', '2018-12-28', '2018-12-31'],
dtype='datetime64[ns]', freq=None)