ENH: Add BusinessHour offset by sinhrks · Pull Request #7905 · pandas-dev/pandas (original) (raw)
Closes #2469. Create BusinessHour
offset to specify business hours on BusinessDay
. Appreciated if any feedbacks regarding bahaviours, keywords, etc.
Basic
By default, use 9:00 - 17:00 as business hours. Adding BusinessHour
will increment timestamp by hourly on the days belong to BusinessDay
offset.
bh = pd.offsets.BusinessHour()
repr(bh)
# <BusinessHour: BH=09:00-17:00>
pd.Timestamp('2014-08-01 10:00') + bh
#2014-08-01 11:00:00
pd.Timestamp('2014-08-01 08:00') + bh
#2014-08-01 10:00:00
# move to next Business Day
pd.Timestamp('2014-08-01 19:00') + bh
#2014-08-04 10:00:00
# if exceeds the closing time, remaining are added to next day
pd.Timestamp('2014-08-01 16:45') + bh
#2014-08-04 09:45:00
# if n != 1
pd.Timestamp('2014-08-01 10:00') + pd.offsets.BusinessHour(2)
#2014-08-01 12:00:00
pd.Timestamp('2014-08-01 10:00') + pd.offsets.BusinessHour(-3)
#2014-07-31 15:00:00
# Create Index
pd.date_range('2014-07-08 10:00', freq='BH', periods=40)
# [2014-07-08 10:00:00, ..., 2014-07-14 17:00:00]
# Length: 40, Freq: BH, Timezone: None
Specify Opening/Closing Hour
Allow to specify opening/closing time using start
and end
keyword by hour:minute
string or datetime.time
.
bh = pd.offsets.BusinessHour(start='11:00', end=datetime.time(20, 0))
repr(bh)
# <BusinessHour: BH=11:00-20:00>
pd.Timestamp('2014-08-01 10:00') + bh
#2014-08-01 12:00:00
pd.Timestamp('2014-08-01 13:00') + bh
#2014-08-01 14:00:00
pd.Timestamp('2014-08-01 19:00') + bh
#2014-08-04 11:00:00
# if end < start, it will be midnight business hour
bh = pd.offsets.BusinessHour(start='17:00', end='9:00')
repr(bh)
# <BusinessHour: BH=17:00-09:00>
pd.Timestamp('2014-07-31 10:00') + bh
#2014-07-31 18:00:00
pd.Timestamp('2014-07-31 23:00') + bh
#2014-08-01 00:00:00
pd.Timestamp('2014-07-31 01:00') + bh
#2014-07-31 02:00:00
pd.Timestamp('2014-08-01 13:00') + bh
#2014-08-01 18:00:00
Edge cases
onOffset
should include both edges.
pd.offsets.BusinessHour().onOffset(pd.Timestamp('2014-08-01 09:00'))
# True
pd.offsets.BusinessHour().onOffset(pd.Timestamp('2014-08-01 17:00'))
# True
If result is on the end-edge of business hour, move to next
# not 2014-08-01 17:00
pd.Timestamp('2014-08-01 16:00') + pd.offsets.BusinessHour()
#2014-08-04 09:00
# not 2014-08-01 09:00
pd.Timestamp('2014-08-01 10:00') - pd.offsets.BusinessHour()
#2014-07:31 17:00
In case of midnight business hour, distinguish the date by its opening hour
#2014-08-02 is Saturday, but handled as valid because its business hour starts on 08-01
pd.Timestamp('2014-08-02 01:00') + pd.offsets.BusinessHour(start='17:00', end='9:00')
#2014-08:02 02:00
Remainings:
- doc
- impl & tests
- Index creation
* Confirm better conditions whether inferred_freq results inBH
orH
normalize
tsplot(This can't be done without ENH: Cleanup backend for Offsets and Period #5148, skipped)- Correct edge handling for
rollback
androllforward
- handling
nanosecond
(minor issue, but currentapply_wraps
may add preservednanosecond
after the closing time)
- Index creation
- tests
n
larger than business shours- Specifying
start
andend
- midnight business hours
- Error cases for initialization
- Better fix for
test_apply_out_of_range
timezone check, which fails because of DST difference.