Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEPR: Deprecate cdate_range and merge into bdate_range #17691

Merged
merged 3 commits into from
Oct 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion doc/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,6 @@ Top-level dealing with datetimelike
to_timedelta
date_range
bdate_range
cdate_range
period_range
timedelta_range
infer_freq
Expand Down
241 changes: 132 additions & 109 deletions doc/source/timeseries.rst

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions doc/source/whatsnew/v0.21.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ Additionally, DataFrames with datetime columns that were parsed by :func:`read_s
Consistency of Range Functions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In previous versions, there were some inconsistencies between the various range functions: :func:`date_range`, :func:`bdate_range`, :func:`cdate_range`, :func:`period_range`, :func:`timedelta_range`, and :func:`interval_range`. (:issue:`17471`).
In previous versions, there were some inconsistencies between the various range functions: :func:`date_range`, :func:`bdate_range`, :func:`period_range`, :func:`timedelta_range`, and :func:`interval_range`. (:issue:`17471`).

One of the inconsistent behaviors occurred when the ``start``, ``end`` and ``period`` parameters were all specified, potentially leading to ambiguous ranges. When all three parameters were passed, ``interval_range`` ignored the ``period`` parameter, ``period_range`` ignored the ``end`` parameter, and the other range functions raised. To promote consistency among the range functions, and avoid potentially ambiguous ranges, ``interval_range`` and ``period_range`` will now raise when all three parameters are passed.

Expand Down Expand Up @@ -571,8 +571,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`, 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 @@ -738,9 +739,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`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for fixing this!

- 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
3 changes: 1 addition & 2 deletions pandas/core/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
PeriodIndex, NaT)
from pandas.core.indexes.period import Period, period_range, pnow
from pandas.core.indexes.timedeltas import Timedelta, timedelta_range
from pandas.core.indexes.datetimes import (Timestamp, date_range, bdate_range,
cdate_range)
from pandas.core.indexes.datetimes import Timestamp, date_range, bdate_range
from pandas.core.indexes.interval import Interval, interval_range

from pandas.core.series import Series
Expand Down
38 changes: 36 additions & 2 deletions pandas/core/indexes/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
is_period_dtype,
is_bool_dtype,
is_string_dtype,
is_string_like,
is_list_like,
is_scalar,
pandas_dtype,
Expand All @@ -37,7 +38,8 @@
Resolution)
from pandas.core.indexes.datetimelike import (
DatelikeOps, TimelikeOps, DatetimeIndexOpsMixin)
from pandas.tseries.offsets import DateOffset, generate_range, Tick, CDay
from pandas.tseries.offsets import (
DateOffset, generate_range, Tick, CDay, prefix_mapping)
from pandas.core.tools.datetimes import (
parse_time_string, normalize_date, to_time)
from pandas.core.tools.timedeltas import to_timedelta
Expand Down Expand Up @@ -2049,7 +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, 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 @@ -2071,6 +2074,20 @@ 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 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
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

closed : string, default None
Make the interval closed with respect to the given frequency to
the 'left', 'right', or both sides (None)
Expand All @@ -2088,6 +2105,18 @@ def bdate_range(start=None, end=None, periods=None, freq='B', tz=None,
rng : DatetimeIndex
"""

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:
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,
closed=closed, **kwargs)
Expand All @@ -2099,6 +2128,8 @@ def cdate_range(start=None, end=None, periods=None, freq='C', tz=None,
Return a fixed frequency DatetimeIndex, with CustomBusinessDay as the
default frequency

.. deprecated:: 0.21.0

Parameters
----------
start : string or datetime-like, default None
Expand Down Expand Up @@ -2137,6 +2168,9 @@ 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 pd.bdate_range(..., freq='{freq}')"
.format(freq=freq), FutureWarning, stacklevel=2)

if freq == 'C':
holidays = kwargs.pop('holidays', [])
Expand Down
12 changes: 11 additions & 1 deletion pandas/tests/api/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class TestPDApi(Base):
# top-level functions
funcs = ['bdate_range', 'concat', 'crosstab', 'cut',
'date_range', 'interval_range', 'eval',
'factorize', 'get_dummies', 'cdate_range',
'factorize', 'get_dummies',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move to the deprecated functions section, and add a test (in same module), model after the top-level deprecations.

'infer_freq', 'isna', 'isnull', 'lreshape',
'melt', 'notna', 'notnull', 'offsets',
'merge', 'merge_ordered', 'merge_asof',
Expand Down Expand Up @@ -240,3 +240,13 @@ def test_deprecation_access_func(self):
[c1, c2],
sort_categories=True,
ignore_order=True)


class TestCDateRange(object):

def test_deprecation_cdaterange(self):
# GH17596
from pandas.core.indexes.datetimes import cdate_range
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import from pandas here (we are actually testing the pd. deprecation); in this case they are the same, but its our practice to use the one we are deprecating.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, we are testing this one (the move to top-level pd namespace was only very recently in master, so we don't have to deprecate that. That one we just removed, and we are deprecating the actual nested one)

Copy link
Contributor

@jreback jreback Oct 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, ok then; guess we moved this in 0.21.0, so this is fine then.

with tm.assert_produces_warning(FutureWarning,
check_stacklevel=False):
cdate_range('2017-01-01', '2017-12-31')
Loading