Skip to content

Commit 7d9e789

Browse files
jschendelalanbato
authored andcommitted
DEPR: Deprecate cdate_range and merge into bdate_range (pandas-dev#17691)
1 parent 3a9111c commit 7d9e789

File tree

10 files changed

+299
-212
lines changed

10 files changed

+299
-212
lines changed

doc/source/api.rst

-1
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,6 @@ Top-level dealing with datetimelike
218218
to_timedelta
219219
date_range
220220
bdate_range
221-
cdate_range
222221
period_range
223222
timedelta_range
224223
infer_freq

doc/source/timeseries.rst

+132-109
Large diffs are not rendered by default.

doc/source/whatsnew/v0.21.0.txt

+5-4
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ Additionally, DataFrames with datetime columns that were parsed by :func:`read_s
488488
Consistency of Range Functions
489489
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
490490

491-
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`).
491+
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`).
492492

493493
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.
494494

@@ -571,8 +571,9 @@ Deprecations
571571
- :func:`SeriesGroupBy.nth` has deprecated ``True`` in favor of ``'all'`` for its kwarg ``dropna`` (:issue:`11038`).
572572
- :func:`DataFrame.as_blocks` is deprecated, as this is exposing the internal implementation (:issue:`17302`)
573573
- ``pd.TimeGrouper`` is deprecated in favor of :class:`pandas.Grouper` (:issue:`16747`)
574+
- ``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`)
574575

575-
.. _whatsnew_0210.deprecations.argmin_min
576+
.. _whatsnew_0210.deprecations.argmin_min:
576577

577578
Series.argmax and Series.argmin
578579
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -738,9 +739,9 @@ Numeric
738739

739740
Categorical
740741
^^^^^^^^^^^
741-
- Bug in :func:`Series.isin` when called with a categorical (:issue`16639`)
742+
- Bug in :func:`Series.isin` when called with a categorical (:issue:`16639`)
742743
- 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`)
743-
- Bug in categorical operations with :ref:`Series.cat <categorical.cat>' not preserving the original Series' name (:issue:`17509`)
744+
- Bug in categorical operations with :ref:`Series.cat <categorical.cat>` not preserving the original Series' name (:issue:`17509`)
744745

745746
PyPy
746747
^^^^

pandas/core/api.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
PeriodIndex, NaT)
1717
from pandas.core.indexes.period import Period, period_range, pnow
1818
from pandas.core.indexes.timedeltas import Timedelta, timedelta_range
19-
from pandas.core.indexes.datetimes import (Timestamp, date_range, bdate_range,
20-
cdate_range)
19+
from pandas.core.indexes.datetimes import Timestamp, date_range, bdate_range
2120
from pandas.core.indexes.interval import Interval, interval_range
2221

2322
from pandas.core.series import Series

pandas/core/indexes/datetimes.py

+36-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
is_period_dtype,
1818
is_bool_dtype,
1919
is_string_dtype,
20+
is_string_like,
2021
is_list_like,
2122
is_scalar,
2223
pandas_dtype,
@@ -37,7 +38,8 @@
3738
Resolution)
3839
from pandas.core.indexes.datetimelike import (
3940
DatelikeOps, TimelikeOps, DatetimeIndexOpsMixin)
40-
from pandas.tseries.offsets import DateOffset, generate_range, Tick, CDay
41+
from pandas.tseries.offsets import (
42+
DateOffset, generate_range, Tick, CDay, prefix_mapping)
4143
from pandas.core.tools.datetimes import (
4244
parse_time_string, normalize_date, to_time)
4345
from pandas.core.tools.timedeltas import to_timedelta
@@ -2049,7 +2051,8 @@ def date_range(start=None, end=None, periods=None, freq='D', tz=None,
20492051

20502052

20512053
def bdate_range(start=None, end=None, periods=None, freq='B', tz=None,
2052-
normalize=True, name=None, closed=None, **kwargs):
2054+
normalize=True, name=None, weekmask=None, holidays=None,
2055+
closed=None, **kwargs):
20532056
"""
20542057
Return a fixed frequency DatetimeIndex, with business day as the default
20552058
frequency
@@ -2071,6 +2074,20 @@ def bdate_range(start=None, end=None, periods=None, freq='B', tz=None,
20712074
Normalize start/end dates to midnight before generating date range
20722075
name : string, default None
20732076
Name of the resulting DatetimeIndex
2077+
weekmask : string or None, default None
2078+
Weekmask of valid business days, passed to ``numpy.busdaycalendar``,
2079+
only used when custom frequency strings are passed. The default
2080+
value None is equivalent to 'Mon Tue Wed Thu Fri'
2081+
2082+
.. versionadded:: 0.21.0
2083+
2084+
holidays : list-like or None, default None
2085+
Dates to exclude from the set of valid business days, passed to
2086+
``numpy.busdaycalendar``, only used when custom frequency strings
2087+
are passed
2088+
2089+
.. versionadded:: 0.21.0
2090+
20742091
closed : string, default None
20752092
Make the interval closed with respect to the given frequency to
20762093
the 'left', 'right', or both sides (None)
@@ -2088,6 +2105,18 @@ def bdate_range(start=None, end=None, periods=None, freq='B', tz=None,
20882105
rng : DatetimeIndex
20892106
"""
20902107

2108+
if is_string_like(freq) and freq.startswith('C'):
2109+
try:
2110+
weekmask = weekmask or 'Mon Tue Wed Thu Fri'
2111+
freq = prefix_mapping[freq](holidays=holidays, weekmask=weekmask)
2112+
except (KeyError, TypeError):
2113+
msg = 'invalid custom frequency string: {freq}'.format(freq=freq)
2114+
raise ValueError(msg)
2115+
elif holidays or weekmask:
2116+
msg = ('a custom frequency string is required when holidays or '
2117+
'weekmask are passed, got frequency {freq}').format(freq=freq)
2118+
raise ValueError(msg)
2119+
20912120
return DatetimeIndex(start=start, end=end, periods=periods,
20922121
freq=freq, tz=tz, normalize=normalize, name=name,
20932122
closed=closed, **kwargs)
@@ -2099,6 +2128,8 @@ def cdate_range(start=None, end=None, periods=None, freq='C', tz=None,
20992128
Return a fixed frequency DatetimeIndex, with CustomBusinessDay as the
21002129
default frequency
21012130
2131+
.. deprecated:: 0.21.0
2132+
21022133
Parameters
21032134
----------
21042135
start : string or datetime-like, default None
@@ -2137,6 +2168,9 @@ def cdate_range(start=None, end=None, periods=None, freq='C', tz=None,
21372168
-------
21382169
rng : DatetimeIndex
21392170
"""
2171+
warnings.warn("cdate_range is deprecated and will be removed in a future "
2172+
"version, instead use pd.bdate_range(..., freq='{freq}')"
2173+
.format(freq=freq), FutureWarning, stacklevel=2)
21402174

21412175
if freq == 'C':
21422176
holidays = kwargs.pop('holidays', [])

pandas/tests/api/test_api.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class TestPDApi(Base):
6363
# top-level functions
6464
funcs = ['bdate_range', 'concat', 'crosstab', 'cut',
6565
'date_range', 'interval_range', 'eval',
66-
'factorize', 'get_dummies', 'cdate_range',
66+
'factorize', 'get_dummies',
6767
'infer_freq', 'isna', 'isnull', 'lreshape',
6868
'melt', 'notna', 'notnull', 'offsets',
6969
'merge', 'merge_ordered', 'merge_asof',
@@ -240,3 +240,13 @@ def test_deprecation_access_func(self):
240240
[c1, c2],
241241
sort_categories=True,
242242
ignore_order=True)
243+
244+
245+
class TestCDateRange(object):
246+
247+
def test_deprecation_cdaterange(self):
248+
# GH17596
249+
from pandas.core.indexes.datetimes import cdate_range
250+
with tm.assert_produces_warning(FutureWarning,
251+
check_stacklevel=False):
252+
cdate_range('2017-01-01', '2017-12-31')

0 commit comments

Comments
 (0)