Skip to content

Commit a05eceb

Browse files
Hamed Saljooghinejadjreback
Hamed Saljooghinejad
authored andcommitted
Index.shift() gives confusing error message when no DatetimeIndex, #8083
1 parent 75f2be6 commit a05eceb

File tree

4 files changed

+63
-9
lines changed

4 files changed

+63
-9
lines changed

doc/source/whatsnew/v0.17.1.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ Enhancements
9898

9999
API changes
100100
~~~~~~~~~~~
101-
101+
- raise ``NotImplementedError`` in ``Index.shift`` for non-supported index types (:issue:`8083`)
102102
- min and max reductions on ``datetime64`` and ``timedelta64`` dtyped series now
103103
result in ``NaT`` and not ``nan`` (:issue:`11245`).
104104
- Regression from 0.16.2 for output formatting of long floats/nan, restored in (:issue:`11302`)

pandas/core/index.py

+1-6
Original file line numberDiff line numberDiff line change
@@ -1461,12 +1461,7 @@ def shift(self, periods=1, freq=None):
14611461
-------
14621462
shifted : Index
14631463
"""
1464-
if periods == 0:
1465-
# OK because immutable
1466-
return self
1467-
1468-
offset = periods * freq
1469-
return Index([idx + offset for idx in self], name=self.name)
1464+
raise NotImplementedError("Not supported for type %s" % type(self).__name__)
14701465

14711466
def argsort(self, *args, **kwargs):
14721467
"""

pandas/tests/test_index.py

+58
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ def test_pickle_compat_construction(self):
5353
# need an object to create with
5454
self.assertRaises(TypeError, self._holder)
5555

56+
def test_shift_index(self):
57+
# err8083 test the base class for shift
58+
idx = self.create_index()
59+
self.assertRaises(NotImplementedError, idx.shift, 1)
60+
61+
self.assertRaises(NotImplementedError, idx.shift, 1, 2)
62+
5663
def test_numeric_compat(self):
5764

5865
idx = self.create_index()
@@ -3425,6 +3432,32 @@ def setUp(self):
34253432
def create_index(self):
34263433
return date_range('20130101', periods=5)
34273434

3435+
def test_shift(self):
3436+
# test shift for datetimeIndex and non datetimeIndex
3437+
# err8083
3438+
3439+
drange = self.create_index()
3440+
result = drange.shift(1)
3441+
expected = DatetimeIndex(['2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05',
3442+
'2013-01-06'], freq='D')
3443+
self.assert_index_equal(result, expected)
3444+
3445+
result = drange.shift(0)
3446+
expected = DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
3447+
'2013-01-05'], freq='D')
3448+
self.assert_index_equal(result, expected)
3449+
3450+
result = drange.shift(-1)
3451+
expected = DatetimeIndex(['2012-12-31','2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04'],
3452+
freq='D')
3453+
self.assert_index_equal(result, expected)
3454+
3455+
result = drange.shift(3, freq='2D')
3456+
expected = DatetimeIndex(['2013-01-07', '2013-01-08', '2013-01-09', '2013-01-10',
3457+
'2013-01-11'],freq='D')
3458+
self.assert_index_equal(result, expected)
3459+
3460+
34283461
def test_construction_with_alt(self):
34293462

34303463
i = pd.date_range('20130101',periods=5,freq='H',tz='US/Eastern')
@@ -3688,6 +3721,16 @@ def setUp(self):
36883721
def create_index(self):
36893722
return period_range('20130101', periods=5, freq='D')
36903723

3724+
def test_shift(self):
3725+
# test shift for PeriodIndex
3726+
# err8083
3727+
3728+
drange = self.create_index()
3729+
result = drange.shift(1)
3730+
expected = PeriodIndex(['2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05',
3731+
'2013-01-06'], freq='D')
3732+
self.assert_index_equal(result, expected)
3733+
36913734
def test_pickle_compat_construction(self):
36923735
pass
36933736

@@ -3784,6 +3827,21 @@ def setUp(self):
37843827
def create_index(self):
37853828
return pd.to_timedelta(range(5), unit='d') + pd.offsets.Hour(1)
37863829

3830+
def test_shift(self):
3831+
# test shift for TimedeltaIndex
3832+
# err8083
3833+
3834+
drange = self.create_index()
3835+
result = drange.shift(1)
3836+
expected = TimedeltaIndex(['1 days 01:00:00', '2 days 01:00:00', '3 days 01:00:00',
3837+
'4 days 01:00:00', '5 days 01:00:00'],freq='D')
3838+
self.assert_index_equal(result, expected)
3839+
3840+
result = drange.shift(3, freq='2D')
3841+
expected = TimedeltaIndex(['2 days 01:00:00', '3 days 01:00:00', '4 days 01:00:00',
3842+
'5 days 01:00:00', '6 days 01:00:00'],freq='D')
3843+
self.assert_index_equal(result, expected)
3844+
37873845
def test_get_loc(self):
37883846
idx = pd.to_timedelta(['0 days', '1 days', '2 days'])
37893847

pandas/tseries/base.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -516,9 +516,10 @@ def shift(self, n, freq=None):
516516
if freq is not None and freq != self.freq:
517517
if isinstance(freq, compat.string_types):
518518
freq = frequencies.to_offset(freq)
519-
result = Index.shift(self, n, freq)
519+
offset = n * freq
520+
result = self + offset
520521

521-
if hasattr(self,'tz'):
522+
if hasattr(self, 'tz'):
522523
result.tz = self.tz
523524

524525
return result

0 commit comments

Comments
 (0)