|
4 | 4 | .. ipython:: python
|
5 | 5 | :suppress:
|
6 | 6 |
|
7 |
| - from datetime import datetime, timedelta |
| 7 | + from datetime import datetime, timedelta, time |
8 | 8 | import numpy as np
|
9 | 9 | np.random.seed(123456)
|
10 | 10 | from pandas import *
|
@@ -482,6 +482,7 @@ frequency increment. Specific offset logic like "month", "business day", or
|
482 | 482 | BYearEnd, "business year end"
|
483 | 483 | BYearBegin, "business year begin"
|
484 | 484 | FY5253, "retail (aka 52-53 week) year"
|
| 485 | + BusinessHour, "business hour" |
485 | 486 | Hour, "one hour"
|
486 | 487 | Minute, "one minute"
|
487 | 488 | Second, "one second"
|
@@ -667,6 +668,102 @@ in the usual way.
|
667 | 668 | have to change to fix the timezone issues, the behaviour of the
|
668 | 669 | ``CustomBusinessDay`` class may have to change in future versions.
|
669 | 670 |
|
| 671 | +.. _timeseries.businesshour: |
| 672 | + |
| 673 | +Business Hour |
| 674 | +~~~~~~~~~~~~~ |
| 675 | + |
| 676 | +The ``BusinessHour`` class provides a business hour representation on ``BusinessDay``, |
| 677 | +allowing to use specific start and end times. |
| 678 | + |
| 679 | +By default, ``BusinessHour`` uses 9:00 - 17:00 as business hours. |
| 680 | +Adding ``BusinessHour`` will increment ``Timestamp`` by hourly. |
| 681 | +If target ``Timestamp`` is out of business hours, move to the next business hour then increment it. |
| 682 | +If the result exceeds the business hours end, remaining is added to the next business day. |
| 683 | + |
| 684 | +.. ipython:: python |
| 685 | +
|
| 686 | + bh = BusinessHour() |
| 687 | + bh |
| 688 | +
|
| 689 | + # 2014-08-01 is Friday |
| 690 | + Timestamp('2014-08-01 10:00').weekday() |
| 691 | + Timestamp('2014-08-01 10:00') + bh |
| 692 | +
|
| 693 | + # Below example is the same as Timestamp('2014-08-01 09:00') + bh |
| 694 | + Timestamp('2014-08-01 08:00') + bh |
| 695 | +
|
| 696 | + # If the results is on the end time, move to the next business day |
| 697 | + Timestamp('2014-08-01 16:00') + bh |
| 698 | +
|
| 699 | + # Remainings are added to the next day |
| 700 | + Timestamp('2014-08-01 16:30') + bh |
| 701 | +
|
| 702 | + # Adding 2 business hours |
| 703 | + Timestamp('2014-08-01 10:00') + BusinessHour(2) |
| 704 | +
|
| 705 | + # Subtracting 3 business hours |
| 706 | + Timestamp('2014-08-01 10:00') + BusinessHour(-3) |
| 707 | +
|
| 708 | +Also, you can specify ``start`` and ``end`` time by keywords. |
| 709 | +Argument must be ``str`` which has ``hour:minute`` representation or ``datetime.time`` instance. |
| 710 | +Specifying seconds, microseconds and nanoseconds as business hour results in ``ValueError``. |
| 711 | + |
| 712 | +.. ipython:: python |
| 713 | +
|
| 714 | + bh = BusinessHour(start='11:00', end=time(20, 0)) |
| 715 | + bh |
| 716 | +
|
| 717 | + Timestamp('2014-08-01 13:00') + bh |
| 718 | + Timestamp('2014-08-01 09:00') + bh |
| 719 | + Timestamp('2014-08-01 18:00') + bh |
| 720 | +
|
| 721 | +Passing ``start`` time later than ``end`` represents midnight business hour. |
| 722 | +In this case, business hour exceeds midnight and overlap to the next day. |
| 723 | +Valid business hours are distinguished by whether it started from valid ``BusinessDay``. |
| 724 | + |
| 725 | +.. ipython:: python |
| 726 | +
|
| 727 | + bh = BusinessHour(start='17:00', end='09:00') |
| 728 | + bh |
| 729 | +
|
| 730 | + Timestamp('2014-08-01 17:00') + bh |
| 731 | + Timestamp('2014-08-01 23:00') + bh |
| 732 | +
|
| 733 | + # Although 2014-08-02 is Satuaday, |
| 734 | + # it is valid because it starts from 08-01 (Friday). |
| 735 | + Timestamp('2014-08-02 04:00') + bh |
| 736 | +
|
| 737 | + # Although 2014-08-04 is Monday, |
| 738 | + # it is out of business hours because it starts from 08-03 (Sunday). |
| 739 | + Timestamp('2014-08-04 04:00') + bh |
| 740 | +
|
| 741 | +Applying ``BusinessHour.rollforward`` and ``rollback`` to out of business hours results in |
| 742 | +the next business hour start or previous day's end. Different from other offsets, ``BusinessHour.rollforward`` |
| 743 | +may output different results from ``apply`` by definition. |
| 744 | + |
| 745 | +This is because one day's business hour end is equal to next day's business hour start. For example, |
| 746 | +under the default business hours (9:00 - 17:00), there is no gap (0 minutes) between ``2014-08-01 17:00`` and |
| 747 | +``2014-08-04 09:00``. |
| 748 | + |
| 749 | +.. ipython:: python |
| 750 | +
|
| 751 | + # This adjusts a Timestamp to business hour edge |
| 752 | + BusinessHour().rollback(Timestamp('2014-08-02 15:00')) |
| 753 | + BusinessHour().rollforward(Timestamp('2014-08-02 15:00')) |
| 754 | +
|
| 755 | + # It is the same as BusinessHour().apply(Timestamp('2014-08-01 17:00')). |
| 756 | + # And it is the same as BusinessHour().apply(Timestamp('2014-08-04 09:00')) |
| 757 | + BusinessHour().apply(Timestamp('2014-08-02 15:00')) |
| 758 | +
|
| 759 | + # BusinessDay results (for reference) |
| 760 | + BusinessHour().rollforward(Timestamp('2014-08-02')) |
| 761 | +
|
| 762 | + # It is the same as BusinessDay().apply(Timestamp('2014-08-01')) |
| 763 | + # The result is the same as rollworward because BusinessDay never overlap. |
| 764 | + BusinessHour().apply(Timestamp('2014-08-02')) |
| 765 | +
|
| 766 | +
|
670 | 767 | Offset Aliases
|
671 | 768 | ~~~~~~~~~~~~~~
|
672 | 769 |
|
@@ -696,6 +793,7 @@ frequencies. We will refer to these aliases as *offset aliases*
|
696 | 793 | "BA", "business year end frequency"
|
697 | 794 | "AS", "year start frequency"
|
698 | 795 | "BAS", "business year start frequency"
|
| 796 | + "BH", "business hour frequency" |
699 | 797 | "H", "hourly frequency"
|
700 | 798 | "T", "minutely frequency"
|
701 | 799 | "S", "secondly frequency"
|
|
0 commit comments