Skip to content

Commit 122fa0c

Browse files
jbrockmendelPingviinituutti
authored andcommitted
DEPR: Deprecate passing range-like arguments to DatetimeIndex, TimedeltaIndex (pandas-dev#23919)
1 parent 33d9086 commit 122fa0c

38 files changed

+266
-212
lines changed

doc/source/whatsnew/v0.24.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,7 @@ Deprecations
10761076
- Timezone converting a tz-aware ``datetime.datetime`` or :class:`Timestamp` with :class:`Timestamp` and the ``tz`` argument is now deprecated. Instead, use :meth:`Timestamp.tz_convert` (:issue:`23579`)
10771077
- :func:`pandas.types.is_period` is deprecated in favor of `pandas.types.is_period_dtype` (:issue:`23917`)
10781078
- :func:`pandas.types.is_datetimetz` is deprecated in favor of `pandas.types.is_datetime64tz` (:issue:`23917`)
1079+
- Creating a :class:`TimedeltaIndex` or :class:`DatetimeIndex` by passing range arguments `start`, `end`, and `periods` is deprecated in favor of :func:`timedelta_range` and :func:`date_range` (:issue:`23919`)
10791080

10801081
.. _whatsnew_0240.deprecations.datetimelike_int_ops:
10811082

pandas/core/indexes/datetimes.py

+35-14
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,13 @@ def _new_DatetimeIndex(cls, d):
5050
# so need to localize
5151
tz = d.pop('tz', None)
5252

53-
result = cls.__new__(cls, verify_integrity=False, **d)
53+
with warnings.catch_warnings():
54+
# we ignore warnings from passing verify_integrity=False
55+
# TODO: If we knew what was going in to **d, we might be able to
56+
# go through _simple_new instead
57+
warnings.simplefilter("ignore")
58+
result = cls.__new__(cls, verify_integrity=False, **d)
59+
5460
if tz is not None:
5561
result = result.tz_localize('UTC').tz_convert(tz)
5662
return result
@@ -220,10 +226,20 @@ def __new__(cls, data=None,
220226
freq=None, start=None, end=None, periods=None, tz=None,
221227
normalize=False, closed=None, ambiguous='raise',
222228
dayfirst=False, yearfirst=False, dtype=None,
223-
copy=False, name=None, verify_integrity=True):
229+
copy=False, name=None, verify_integrity=None):
230+
231+
if verify_integrity is not None:
232+
warnings.warn("The 'verify_integrity' argument is deprecated, "
233+
"will be removed in a future version.",
234+
FutureWarning, stacklevel=2)
235+
else:
236+
verify_integrity = True
224237

225238
if data is None:
226-
# TODO: Remove this block and associated kwargs; GH#20535
239+
warnings.warn("Creating a DatetimeIndex by passing range "
240+
"endpoints is deprecated. Use "
241+
"`pandas.date_range` instead.",
242+
FutureWarning, stacklevel=2)
227243
result = cls._generate_range(start, end, periods,
228244
freq=freq, tz=tz, normalize=normalize,
229245
closed=closed, ambiguous=ambiguous)
@@ -756,8 +772,8 @@ def snap(self, freq='S'):
756772
snapped[i] = s
757773

758774
# we know it conforms; skip check
759-
return DatetimeIndex(snapped, freq=freq, verify_integrity=False)
760-
# TODO: what about self.name? if so, use shallow_copy?
775+
return DatetimeIndex._simple_new(snapped, freq=freq)
776+
# TODO: what about self.name? tz? if so, use shallow_copy?
761777

762778
def unique(self, level=None):
763779
if level is not None:
@@ -1519,9 +1535,13 @@ def date_range(start=None, end=None, periods=None, freq=None, tz=None,
15191535
if freq is None and com._any_none(periods, start, end):
15201536
freq = 'D'
15211537

1522-
return DatetimeIndex(start=start, end=end, periods=periods,
1523-
freq=freq, tz=tz, normalize=normalize, name=name,
1524-
closed=closed, **kwargs)
1538+
result = DatetimeIndex._generate_range(
1539+
start=start, end=end, periods=periods,
1540+
freq=freq, tz=tz, normalize=normalize,
1541+
closed=closed, **kwargs)
1542+
1543+
result.name = name
1544+
return result
15251545

15261546

15271547
def bdate_range(start=None, end=None, periods=None, freq='B', tz=None,
@@ -1607,9 +1627,9 @@ def bdate_range(start=None, end=None, periods=None, freq='B', tz=None,
16071627
'weekmask are passed, got frequency {freq}').format(freq=freq)
16081628
raise ValueError(msg)
16091629

1610-
return DatetimeIndex(start=start, end=end, periods=periods,
1611-
freq=freq, tz=tz, normalize=normalize, name=name,
1612-
closed=closed, **kwargs)
1630+
return date_range(start=start, end=end, periods=periods,
1631+
freq=freq, tz=tz, normalize=normalize, name=name,
1632+
closed=closed, **kwargs)
16131633

16141634

16151635
def cdate_range(start=None, end=None, periods=None, freq='C', tz=None,
@@ -1666,9 +1686,10 @@ def cdate_range(start=None, end=None, periods=None, freq='C', tz=None,
16661686
holidays = kwargs.pop('holidays', [])
16671687
weekmask = kwargs.pop('weekmask', 'Mon Tue Wed Thu Fri')
16681688
freq = CDay(holidays=holidays, weekmask=weekmask)
1669-
return DatetimeIndex(start=start, end=end, periods=periods, freq=freq,
1670-
tz=tz, normalize=normalize, name=name,
1671-
closed=closed, **kwargs)
1689+
1690+
return date_range(start=start, end=end, periods=periods, freq=freq,
1691+
tz=tz, normalize=normalize, name=name,
1692+
closed=closed, **kwargs)
16721693

16731694

16741695
def _time_to_micros(time):

pandas/core/indexes/timedeltas.py

+18-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
""" implement the TimedeltaIndex """
22
from datetime import datetime
3+
import warnings
34

45
import numpy as np
56

@@ -132,12 +133,22 @@ def _join_i8_wrapper(joinf, **kwargs):
132133

133134
def __new__(cls, data=None, unit=None, freq=None, start=None, end=None,
134135
periods=None, closed=None, dtype=None, copy=False,
135-
name=None, verify_integrity=True):
136+
name=None, verify_integrity=None):
137+
138+
if verify_integrity is not None:
139+
warnings.warn("The 'verify_integrity' argument is deprecated, "
140+
"will be removed in a future version.",
141+
FutureWarning, stacklevel=2)
142+
else:
143+
verify_integrity = True
136144

137145
freq, freq_infer = dtl.maybe_infer_freq(freq)
138146

139147
if data is None:
140-
# TODO: Remove this block and associated kwargs; GH#20535
148+
warnings.warn("Creating a TimedeltaIndex by passing range "
149+
"endpoints is deprecated. Use "
150+
"`pandas.timedelta_range` instead.",
151+
FutureWarning, stacklevel=2)
141152
result = cls._generate_range(start, end, periods, freq,
142153
closed=closed)
143154
result.name = name
@@ -740,5 +751,8 @@ def timedelta_range(start=None, end=None, periods=None, freq=None,
740751
if freq is None and com._any_none(periods, start, end):
741752
freq = 'D'
742753

743-
return TimedeltaIndex(start=start, end=end, periods=periods,
744-
freq=freq, name=name, closed=closed)
754+
freq, freq_infer = dtl.maybe_infer_freq(freq)
755+
result = TimedeltaIndex._generate_range(start, end, periods, freq,
756+
closed=closed)
757+
result.name = name
758+
return result

pandas/core/resample.py

+10-10
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from pandas.core.groupby.ops import BinGrouper
2727
from pandas.core.indexes.datetimes import DatetimeIndex, date_range
2828
from pandas.core.indexes.period import PeriodIndex
29-
from pandas.core.indexes.timedeltas import TimedeltaIndex
29+
from pandas.core.indexes.timedeltas import TimedeltaIndex, timedelta_range
3030

3131
from pandas.tseries.frequencies import is_subperiod, is_superperiod, to_offset
3232
from pandas.tseries.offsets import (
@@ -1398,11 +1398,11 @@ def _get_time_bins(self, ax):
13981398
# because replace() will swallow the nanosecond part
13991399
# thus last bin maybe slightly before the end if the end contains
14001400
# nanosecond part and lead to `Values falls after last bin` error
1401-
binner = labels = DatetimeIndex(freq=self.freq,
1402-
start=first,
1403-
end=last,
1404-
tz=tz,
1405-
name=ax.name)
1401+
binner = labels = date_range(freq=self.freq,
1402+
start=first,
1403+
end=last,
1404+
tz=tz,
1405+
name=ax.name)
14061406

14071407
# GH 15549
14081408
# In edge case of tz-aware resapmling binner last index can be
@@ -1484,10 +1484,10 @@ def _get_time_delta_bins(self, ax):
14841484
return binner, [], labels
14851485

14861486
start, end = ax.min(), ax.max()
1487-
labels = binner = TimedeltaIndex(start=start,
1488-
end=end,
1489-
freq=self.freq,
1490-
name=ax.name)
1487+
labels = binner = timedelta_range(start=start,
1488+
end=end,
1489+
freq=self.freq,
1490+
name=ax.name)
14911491

14921492
end_stamps = labels + self.freq
14931493
bins = ax.searchsorted(end_stamps, side='left')

pandas/io/packers.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -604,8 +604,8 @@ def decode(obj):
604604

605605
elif typ == u'datetime_index':
606606
data = unconvert(obj[u'data'], np.int64, obj.get(u'compress'))
607-
d = dict(name=obj[u'name'], freq=obj[u'freq'], verify_integrity=False)
608-
result = globals()[obj[u'klass']](data, **d)
607+
d = dict(name=obj[u'name'], freq=obj[u'freq'])
608+
result = DatetimeIndex._simple_new(data, **d)
609609
tz = obj[u'tz']
610610

611611
# reverse tz conversion

pandas/tests/frame/test_indexing.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ def test_setitem_boolean_column(self):
647647

648648
def test_frame_setitem_timestamp(self):
649649
# GH#2155
650-
columns = DatetimeIndex(start='1/1/2012', end='2/1/2012', freq=BDay())
650+
columns = date_range(start='1/1/2012', end='2/1/2012', freq=BDay())
651651
index = lrange(10)
652652
data = DataFrame(columns=columns, index=index)
653653
t = datetime(2012, 11, 1)

pandas/tests/groupby/test_groupby.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from pandas import (date_range, Timestamp,
1010
Index, MultiIndex, DataFrame, Series,
11-
Panel, DatetimeIndex, read_csv)
11+
Panel, read_csv)
1212
from pandas.errors import PerformanceWarning
1313
from pandas.util.testing import (assert_frame_equal,
1414
assert_series_equal, assert_almost_equal)
@@ -1438,7 +1438,7 @@ def test_groupby_sort_multiindex_series():
14381438
def test_groupby_reindex_inside_function():
14391439

14401440
periods = 1000
1441-
ind = DatetimeIndex(start='2012/1/1', freq='5min', periods=periods)
1441+
ind = date_range(start='2012/1/1', freq='5min', periods=periods)
14421442
df = DataFrame({'high': np.arange(
14431443
periods), 'low': np.arange(periods)}, index=ind)
14441444

pandas/tests/groupby/test_timegrouper.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
import pandas as pd
1111
from pandas import (DataFrame, date_range, Index,
12-
Series, MultiIndex, Timestamp, DatetimeIndex)
12+
Series, MultiIndex, Timestamp)
1313
from pandas.core.groupby.ops import BinGrouper
1414
from pandas.compat import StringIO
1515
from pandas.util import testing as tm
@@ -374,9 +374,9 @@ def sumfunc_value(x):
374374
expected.reset_index(drop=True))
375375

376376
def test_groupby_groups_datetimeindex(self):
377-
# #1430
377+
# GH#1430
378378
periods = 1000
379-
ind = DatetimeIndex(start='2012/1/1', freq='5min', periods=periods)
379+
ind = pd.date_range(start='2012/1/1', freq='5min', periods=periods)
380380
df = DataFrame({'high': np.arange(periods),
381381
'low': np.arange(periods)}, index=ind)
382382
grouped = df.groupby(lambda x: datetime(x.year, x.month, x.day))
@@ -385,7 +385,7 @@ def test_groupby_groups_datetimeindex(self):
385385
groups = grouped.groups
386386
assert isinstance(list(groups.keys())[0], datetime)
387387

388-
# GH 11442
388+
# GH#11442
389389
index = pd.date_range('2015/01/01', periods=5, name='date')
390390
df = pd.DataFrame({'A': [5, 6, 7, 8, 9],
391391
'B': [1, 2, 3, 4, 5]}, index=index)

pandas/tests/indexes/datetimes/test_construction.py

+35-24
Original file line numberDiff line numberDiff line change
@@ -347,17 +347,28 @@ def test_construction_with_ndarray(self):
347347
freq='B')
348348
tm.assert_index_equal(result, expected)
349349

350+
def test_verify_integrity_deprecated(self):
351+
# GH#23919
352+
with tm.assert_produces_warning(FutureWarning):
353+
DatetimeIndex(['1/1/2000'], verify_integrity=False)
354+
355+
def test_range_kwargs_deprecated(self):
356+
# GH#23919
357+
with tm.assert_produces_warning(FutureWarning):
358+
DatetimeIndex(start='1/1/2000', end='1/10/2000', freq='D')
359+
350360
def test_constructor_coverage(self):
351361
rng = date_range('1/1/2000', periods=10.5)
352362
exp = date_range('1/1/2000', periods=10)
353363
tm.assert_index_equal(rng, exp)
354364

355365
msg = 'periods must be a number, got foo'
356366
with pytest.raises(TypeError, match=msg):
357-
DatetimeIndex(start='1/1/2000', periods='foo', freq='D')
367+
date_range(start='1/1/2000', periods='foo', freq='D')
358368

359-
pytest.raises(ValueError, DatetimeIndex, start='1/1/2000',
360-
end='1/10/2000')
369+
with pytest.raises(ValueError):
370+
with tm.assert_produces_warning(FutureWarning):
371+
DatetimeIndex(start='1/1/2000', end='1/10/2000')
361372

362373
with pytest.raises(TypeError):
363374
DatetimeIndex('1/1/2000')
@@ -391,11 +402,11 @@ def test_constructor_coverage(self):
391402
pytest.raises(ValueError, DatetimeIndex,
392403
['2000-01-01', '2000-01-02', '2000-01-04'], freq='D')
393404

394-
pytest.raises(ValueError, DatetimeIndex, start='2011-01-01',
405+
pytest.raises(ValueError, date_range, start='2011-01-01',
395406
freq='b')
396-
pytest.raises(ValueError, DatetimeIndex, end='2011-01-01',
407+
pytest.raises(ValueError, date_range, end='2011-01-01',
397408
freq='B')
398-
pytest.raises(ValueError, DatetimeIndex, periods=10, freq='D')
409+
pytest.raises(ValueError, date_range, periods=10, freq='D')
399410

400411
@pytest.mark.parametrize('freq', ['AS', 'W-SUN'])
401412
def test_constructor_datetime64_tzformat(self, freq):
@@ -476,8 +487,8 @@ def test_constructor_dtype(self):
476487
tm.assert_index_equal(idx, result)
477488

478489
def test_constructor_name(self):
479-
idx = DatetimeIndex(start='2000-01-01', periods=1, freq='A',
480-
name='TEST')
490+
idx = date_range(start='2000-01-01', periods=1, freq='A',
491+
name='TEST')
481492
assert idx.name == 'TEST'
482493

483494
def test_000constructor_resolution(self):
@@ -500,7 +511,7 @@ def test_constructor_start_end_with_tz(self, tz):
500511
# GH 18595
501512
start = Timestamp('2013-01-01 06:00:00', tz='America/Los_Angeles')
502513
end = Timestamp('2013-01-02 06:00:00', tz='America/Los_Angeles')
503-
result = DatetimeIndex(freq='D', start=start, end=end, tz=tz)
514+
result = date_range(freq='D', start=start, end=end, tz=tz)
504515
expected = DatetimeIndex(['2013-01-01 06:00:00',
505516
'2013-01-02 06:00:00'],
506517
tz='America/Los_Angeles')
@@ -616,7 +627,7 @@ def test_ctor_str_intraday(self):
616627
assert rng[0].second == 1
617628

618629
def test_is_(self):
619-
dti = DatetimeIndex(start='1/1/2005', end='12/1/2005', freq='M')
630+
dti = date_range(start='1/1/2005', end='12/1/2005', freq='M')
620631
assert dti.is_(dti)
621632
assert dti.is_(dti.view())
622633
assert not dti.is_(dti.copy())
@@ -644,12 +655,12 @@ def test_constructor_int64_nocopy(self):
644655
@pytest.mark.parametrize('freq', ['M', 'Q', 'A', 'D', 'B', 'BH',
645656
'T', 'S', 'L', 'U', 'H', 'N', 'C'])
646657
def test_from_freq_recreate_from_data(self, freq):
647-
org = DatetimeIndex(start='2001/02/01 09:00', freq=freq, periods=1)
658+
org = date_range(start='2001/02/01 09:00', freq=freq, periods=1)
648659
idx = DatetimeIndex(org, freq=freq)
649660
tm.assert_index_equal(idx, org)
650661

651-
org = DatetimeIndex(start='2001/02/01 09:00', freq=freq,
652-
tz='US/Pacific', periods=1)
662+
org = date_range(start='2001/02/01 09:00', freq=freq,
663+
tz='US/Pacific', periods=1)
653664
idx = DatetimeIndex(org, freq=freq, tz='US/Pacific')
654665
tm.assert_index_equal(idx, org)
655666

@@ -688,30 +699,30 @@ def test_datetimeindex_constructor_misc(self):
688699

689700
sdate = datetime(1999, 12, 25)
690701
edate = datetime(2000, 1, 1)
691-
idx = DatetimeIndex(start=sdate, freq='1B', periods=20)
702+
idx = date_range(start=sdate, freq='1B', periods=20)
692703
assert len(idx) == 20
693704
assert idx[0] == sdate + 0 * offsets.BDay()
694705
assert idx.freq == 'B'
695706

696-
idx = DatetimeIndex(end=edate, freq=('D', 5), periods=20)
707+
idx = date_range(end=edate, freq=('D', 5), periods=20)
697708
assert len(idx) == 20
698709
assert idx[-1] == edate
699710
assert idx.freq == '5D'
700711

701-
idx1 = DatetimeIndex(start=sdate, end=edate, freq='W-SUN')
702-
idx2 = DatetimeIndex(start=sdate, end=edate,
703-
freq=offsets.Week(weekday=6))
712+
idx1 = date_range(start=sdate, end=edate, freq='W-SUN')
713+
idx2 = date_range(start=sdate, end=edate,
714+
freq=offsets.Week(weekday=6))
704715
assert len(idx1) == len(idx2)
705716
assert idx1.freq == idx2.freq
706717

707-
idx1 = DatetimeIndex(start=sdate, end=edate, freq='QS')
708-
idx2 = DatetimeIndex(start=sdate, end=edate,
709-
freq=offsets.QuarterBegin(startingMonth=1))
718+
idx1 = date_range(start=sdate, end=edate, freq='QS')
719+
idx2 = date_range(start=sdate, end=edate,
720+
freq=offsets.QuarterBegin(startingMonth=1))
710721
assert len(idx1) == len(idx2)
711722
assert idx1.freq == idx2.freq
712723

713-
idx1 = DatetimeIndex(start=sdate, end=edate, freq='BQ')
714-
idx2 = DatetimeIndex(start=sdate, end=edate,
715-
freq=offsets.BQuarterEnd(startingMonth=12))
724+
idx1 = date_range(start=sdate, end=edate, freq='BQ')
725+
idx2 = date_range(start=sdate, end=edate,
726+
freq=offsets.BQuarterEnd(startingMonth=12))
716727
assert len(idx1) == len(idx2)
717728
assert idx1.freq == idx2.freq

0 commit comments

Comments
 (0)