diff --git a/doc/source/whatsnew/v0.17.1.txt b/doc/source/whatsnew/v0.17.1.txt index c4e8ae44011ec..61282343f7667 100755 --- a/doc/source/whatsnew/v0.17.1.txt +++ b/doc/source/whatsnew/v0.17.1.txt @@ -98,7 +98,7 @@ Enhancements API changes ~~~~~~~~~~~ - +- raise ``NotImplementedError`` in ``Index.shift`` for non-supported index types (:issue:`8083`) - min and max reductions on ``datetime64`` and ``timedelta64`` dtyped series now result in ``NaT`` and not ``nan`` (:issue:`11245`). - Regression from 0.16.2 for output formatting of long floats/nan, restored in (:issue:`11302`) diff --git a/pandas/core/index.py b/pandas/core/index.py index 9ccde5502ec1b..b0cd72e572c09 100644 --- a/pandas/core/index.py +++ b/pandas/core/index.py @@ -1461,12 +1461,7 @@ def shift(self, periods=1, freq=None): ------- shifted : Index """ - if periods == 0: - # OK because immutable - return self - - offset = periods * freq - return Index([idx + offset for idx in self], name=self.name) + raise NotImplementedError("Not supported for type %s" % type(self).__name__) def argsort(self, *args, **kwargs): """ diff --git a/pandas/tests/test_index.py b/pandas/tests/test_index.py index bd02836953ffd..88700fc8c8605 100644 --- a/pandas/tests/test_index.py +++ b/pandas/tests/test_index.py @@ -53,6 +53,13 @@ def test_pickle_compat_construction(self): # need an object to create with self.assertRaises(TypeError, self._holder) + def test_shift_index(self): + # err8083 test the base class for shift + idx = self.create_index() + self.assertRaises(NotImplementedError, idx.shift, 1) + + self.assertRaises(NotImplementedError, idx.shift, 1, 2) + def test_numeric_compat(self): idx = self.create_index() @@ -3425,6 +3432,32 @@ def setUp(self): def create_index(self): return date_range('20130101', periods=5) + def test_shift(self): + # test shift for datetimeIndex and non datetimeIndex + # err8083 + + drange = self.create_index() + result = drange.shift(1) + expected = DatetimeIndex(['2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', + '2013-01-06'], freq='D') + self.assert_index_equal(result, expected) + + result = drange.shift(0) + expected = DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', + '2013-01-05'], freq='D') + self.assert_index_equal(result, expected) + + result = drange.shift(-1) + expected = DatetimeIndex(['2012-12-31','2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04'], + freq='D') + self.assert_index_equal(result, expected) + + result = drange.shift(3, freq='2D') + expected = DatetimeIndex(['2013-01-07', '2013-01-08', '2013-01-09', '2013-01-10', + '2013-01-11'],freq='D') + self.assert_index_equal(result, expected) + + def test_construction_with_alt(self): i = pd.date_range('20130101',periods=5,freq='H',tz='US/Eastern') @@ -3688,6 +3721,16 @@ def setUp(self): def create_index(self): return period_range('20130101', periods=5, freq='D') + def test_shift(self): + # test shift for PeriodIndex + # err8083 + + drange = self.create_index() + result = drange.shift(1) + expected = PeriodIndex(['2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', + '2013-01-06'], freq='D') + self.assert_index_equal(result, expected) + def test_pickle_compat_construction(self): pass @@ -3784,6 +3827,21 @@ def setUp(self): def create_index(self): return pd.to_timedelta(range(5), unit='d') + pd.offsets.Hour(1) + def test_shift(self): + # test shift for TimedeltaIndex + # err8083 + + drange = self.create_index() + result = drange.shift(1) + expected = TimedeltaIndex(['1 days 01:00:00', '2 days 01:00:00', '3 days 01:00:00', + '4 days 01:00:00', '5 days 01:00:00'],freq='D') + self.assert_index_equal(result, expected) + + result = drange.shift(3, freq='2D') + expected = TimedeltaIndex(['2 days 01:00:00', '3 days 01:00:00', '4 days 01:00:00', + '5 days 01:00:00', '6 days 01:00:00'],freq='D') + self.assert_index_equal(result, expected) + def test_get_loc(self): idx = pd.to_timedelta(['0 days', '1 days', '2 days']) diff --git a/pandas/tseries/base.py b/pandas/tseries/base.py index d5382e8057f4b..b063360b91280 100644 --- a/pandas/tseries/base.py +++ b/pandas/tseries/base.py @@ -516,9 +516,10 @@ def shift(self, n, freq=None): if freq is not None and freq != self.freq: if isinstance(freq, compat.string_types): freq = frequencies.to_offset(freq) - result = Index.shift(self, n, freq) + offset = n * freq + result = self + offset - if hasattr(self,'tz'): + if hasattr(self, 'tz'): result.tz = self.tz return result