Skip to content

Commit

Permalink
review updates
Browse files Browse the repository at this point in the history
  • Loading branch information
jschendel committed Sep 29, 2017
1 parent f64ab7d commit 7306a73
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 35 deletions.
42 changes: 31 additions & 11 deletions doc/source/timeseries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Class Remarks How to create
.. _timeseries.representation:

Timestamps vs. Time Spans
--------------------------
-------------------------

Timestamped data is the most basic type of time series data that associates
values with points in time. For pandas objects it means using the points in
Expand Down Expand Up @@ -263,12 +263,10 @@ pandas supports converting integer or float epoch times to ``Timestamp`` and
``DatetimeIndex``. The default unit is nanoseconds, since that is how ``Timestamp``
objects are stored internally. However, epochs are often stored in another ``unit``
which can be specified. These are computed from the starting point specified by the
:ref:`Origin Parameter <timeseries.origin>`.
``origin`` parameter.

.. ipython:: python
pd.Timestamp(1349720105, unit='s')
pd.to_datetime([1349720105, 1349806505, 1349892905,
1349979305, 1350065705], unit='s')
Expand All @@ -292,6 +290,10 @@ which can be specified. These are computed from the starting point specified by
pd.to_datetime([1490195805.433, 1490195805.433502912], unit='s')
pd.to_datetime(1490195805433502912, unit='ns')
.. seealso::

:ref:`timeseries.origin`

.. _timeseries.converting.epoch_inverse:

From Timestamps to Epoch
Expand All @@ -312,8 +314,8 @@ We convert the ``DatetimeIndex`` to an ``int64`` array, then divide by the conve
.. _timeseries.origin:

Using the Origin Parameter
~~~~~~~~~~~~~~~~~~~~~~~~~~
Using the ``origin`` Parameter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 0.20.0

Expand Down Expand Up @@ -353,7 +355,7 @@ To generate an index with timestamps, you can use either the ``DatetimeIndex`` o
In practice this becomes very cumbersome because we often need a very long
index with a large number of timestamps. If we need timestamps on a regular
frequency, we can use the ``date_range`` and ``bdate_range`` functions
frequency, we can use the :func:`date_range` and :func:`bdate_range` functions
to create a ``DatetimeIndex``. The default frequency for ``date_range`` is a
**calendar day** while the default for ``bdate_range`` is a **business day**:

Expand Down Expand Up @@ -392,11 +394,16 @@ of those specified will not be generated:
pd.bdate_range(start=start, periods=20)
.. _timeseries.custom-freq-ranges:

Custom Frequency Ranges
~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 0.21.0

``bdate_range`` can also generate a range of custom frequency dates by using
the ``weekmask`` and ``holidays`` parameters. These parameters will only be
used if a custom frequency string is passed:
used if a custom frequency string is passed.

.. ipython:: python
Expand All @@ -406,8 +413,19 @@ used if a custom frequency string is passed:
pd.bdate_range(start, end, freq='C', weekmask=weekmask, holidays=holidays)
See the :ref:`Custom Business Days <timeseries.custombusinessdays>` section for
additional information on custom frequencies.
pd.bdate_range(start, end, freq='CBMS', weekmask=weekmask)
.. warning::

This functionality was originally exclusive to ``cdate_range``, which is
deprecated as of version 0.21.0 in favor of ``bdate_range``. Note that
``cdate_range`` only utilizes the ``weekmask`` and ``holidays`` parameters
when custom business day, 'C', is passed as the frequency string. Support has
been expanded with ``bdate_range`` to work with any custom frequency string.

.. seealso::

:ref:`timeseries.custombusinessdays`

.. _timeseries.timestamp-limits:

Expand All @@ -422,7 +440,9 @@ can be represented using a 64-bit integer is limited to approximately 584 years:
pd.Timestamp.min
pd.Timestamp.max
See :ref:`here <timeseries.oob>` for ways to represent data outside these bound.
.. seealso::

:ref:`timeseries.oob`

.. _timeseries.datetimeindex:

Expand Down
9 changes: 4 additions & 5 deletions doc/source/whatsnew/v0.21.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ Other Enhancements
- :func:`read_excel` raises ``ImportError`` with a better message if ``xlrd`` is not installed. (:issue:`17613`)
- :func:`read_json` now accepts a ``chunksize`` parameter that can be used when ``lines=True``. If ``chunksize`` is passed, read_json now returns an iterator which reads in ``chunksize`` lines with each iteration. (:issue:`17048`)
- :meth:`DataFrame.assign` will preserve the original order of ``**kwargs`` for Python 3.6+ users instead of sorting the column names
- :func:`bdate_range` has gained ``weekmask`` and ``holidays`` parameters for constructing custom frequency date ranges (:issue:`17596`)


.. _whatsnew_0210.api_breaking:
Expand Down Expand Up @@ -495,9 +494,9 @@ Deprecations
- :func:`SeriesGroupBy.nth` has deprecated ``True`` in favor of ``'all'`` for its kwarg ``dropna`` (:issue:`11038`).
- :func:`DataFrame.as_blocks` is deprecated, as this is exposing the internal implementation (:issue:`17302`)
- ``pd.TimeGrouper`` is deprecated in favor of :class:`pandas.Grouper` (:issue:`16747`)
- ``cdate_range`` has been deprecated in favor of :func:`bdate_range` (:issue:`17596`)
- ``cdate_range`` has been deprecated in favor of :func:`bdate_range`, which has gained ``weekmask`` and ``holidays`` parameters for building custom frequency date ranges. See the :ref:`documentation <timeseries.custom-freq-ranges>` for more details (:issue:`17596`)

.. _whatsnew_0210.deprecations.argmin_min
.. _whatsnew_0210.deprecations.argmin_min:

Series.argmax and Series.argmin
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -659,9 +658,9 @@ Numeric

Categorical
^^^^^^^^^^^
- Bug in :func:`Series.isin` when called with a categorical (:issue`16639`)
- Bug in :func:`Series.isin` when called with a categorical (:issue:`16639`)
- Bug in the categorical constructor with empty values and categories causing the ``.categories`` to be an empty ``Float64Index`` rather than an empty ``Index`` with object dtype (:issue:`17248`)
- Bug in categorical operations with :ref:`Series.cat <categorical.cat>' not preserving the original Series' name (:issue:`17509`)
- Bug in categorical operations with :ref:`Series.cat <categorical.cat>` not preserving the original Series' name (:issue:`17509`)

PyPy
^^^^
Expand Down
27 changes: 15 additions & 12 deletions pandas/core/indexes/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2051,8 +2051,8 @@ def date_range(start=None, end=None, periods=None, freq='D', tz=None,


def bdate_range(start=None, end=None, periods=None, freq='B', tz=None,
normalize=True, name=None, weekmask='Mon Tue Wed Thu Fri',
holidays=None, closed=None, **kwargs):
normalize=True, name=None, weekmask=None, holidays=None,
closed=None, **kwargs):
"""
Return a fixed frequency DatetimeIndex, with business day as the default
frequency
Expand All @@ -2074,16 +2074,17 @@ def bdate_range(start=None, end=None, periods=None, freq='B', tz=None,
Normalize start/end dates to midnight before generating date range
name : string, default None
Name of the resulting DatetimeIndex
weekmask : string, default 'Mon Tue Wed Thu Fri'
weekmask of valid business days, passed to ``numpy.busdaycalendar``,
only used when custom frequency strings are passed
weekmask : string or None, default None
Weekmask of valid business days, passed to ``numpy.busdaycalendar``,
only used when custom frequency strings are passed. The default
value None is equivalent to 'Mon Tue Wed Thu Fri'
.. versionadded:: 0.21.0
holidays : list-like or None, default None
list-like of dates to exclude from the set of valid business days,
passed to ``numpy.busdaycalendar``, only used when custom frequency
strings are passed
Dates to exclude from the set of valid business days, passed to
``numpy.busdaycalendar``, only used when custom frequency strings
are passed
.. versionadded:: 0.21.0
Expand All @@ -2106,13 +2107,15 @@ def bdate_range(start=None, end=None, periods=None, freq='B', tz=None,

if is_string_like(freq) and freq.startswith('C'):
try:
weekmask = weekmask or 'Mon Tue Wed Thu Fri'
freq = prefix_mapping[freq](holidays=holidays, weekmask=weekmask)
except (KeyError, TypeError):
msg = 'invalid custom frequency string: {freq}'.format(freq=freq)
raise ValueError(msg)
elif holidays or (weekmask != 'Mon Tue Wed Thu Fri'):
warnings.warn('a custom frequency string was not passed, ignoring '
'parameters: holidays, weekmask', UserWarning)
elif holidays or weekmask:
msg = ('a custom frequency string is required when holidays or '
'weekmask are passed, got frequency {freq}').format(freq=freq)
raise ValueError(msg)

return DatetimeIndex(start=start, end=end, periods=periods,
freq=freq, tz=tz, normalize=normalize, name=name,
Expand Down Expand Up @@ -2166,7 +2169,7 @@ def cdate_range(start=None, end=None, periods=None, freq='C', tz=None,
rng : DatetimeIndex
"""
warnings.warn("cdate_range is deprecated and will be removed in a future "
"version, instead use bdate_range(..., freq='{freq}')"
"version, instead use pd.bdate_range(..., freq='{freq}')"
.format(freq=freq), FutureWarning, stacklevel=2)

if freq == 'C':
Expand Down
20 changes: 13 additions & 7 deletions pandas/tests/indexes/datetimes/test_date_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -589,8 +589,10 @@ def test_cdaterange_weekmask(self):
expected = DatetimeIndex(['2013-05-01', '2013-05-02', '2013-05-05'])
tm.assert_index_equal(result, expected)

# warning with non-custom freq
with tm.assert_produces_warning(UserWarning):
# raise with non-custom freq
msg = ('a custom frequency string is required when holidays or '
'weekmask are passed, got frequency B')
with tm.assert_raises_regex(ValueError, msg):
bdate_range('2013-05-01', periods=3,
weekmask='Sun Mon Tue Wed Thu')

Expand All @@ -600,8 +602,10 @@ def test_cdaterange_holidays(self):
expected = DatetimeIndex(['2013-05-02', '2013-05-03', '2013-05-06'])
tm.assert_index_equal(result, expected)

# warning with non-custom freq
with tm.assert_produces_warning(UserWarning):
# raise with non-custom freq
msg = ('a custom frequency string is required when holidays or '
'weekmask are passed, got frequency B')
with tm.assert_raises_regex(ValueError, msg):
bdate_range('2013-05-01', periods=3, holidays=['2013-05-01'])

def test_cdaterange_weekmask_and_holidays(self):
Expand All @@ -611,8 +615,10 @@ def test_cdaterange_weekmask_and_holidays(self):
expected = DatetimeIndex(['2013-05-02', '2013-05-05', '2013-05-06'])
tm.assert_index_equal(result, expected)

# warning with non-custom freq
with tm.assert_produces_warning(UserWarning):
# raise with non-custom freq
msg = ('a custom frequency string is required when holidays or '
'weekmask are passed, got frequency B')
with tm.assert_raises_regex(ValueError, msg):
bdate_range('2013-05-01', periods=3,
weekmask='Sun Mon Tue Wed Thu',
holidays=['2013-05-01'])
Expand All @@ -629,7 +635,7 @@ def test_all_custom_freq(self, freq):
with tm.assert_raises_regex(ValueError, msg.format(freq=bad_freq)):
bdate_range(START, END, freq=bad_freq)

def test_depr_cdaterange(self):
def test_deprecation_cdaterange(self):
# GH17596
with tm.assert_produces_warning(FutureWarning):
cdate_range(START, END)

0 comments on commit 7306a73

Please sign in to comment.