From 9ab2d4db39bc951104642ab1a6f27ce32b7741a6 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 6 Dec 2018 13:32:19 +0200 Subject: [PATCH 001/108] ENH: fill_value argument for shift --- pandas/core/arrays/datetimelike.py | 6 ++--- pandas/core/frame.py | 4 ++-- pandas/core/generic.py | 8 +++---- pandas/core/internals/blocks.py | 4 ++-- pandas/core/series.py | 4 ++-- pandas/tests/series/test_timeseries.py | 31 ++++++++++++++++++++++++++ 6 files changed, 44 insertions(+), 13 deletions(-) diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 45eec41e498d1..a77faabd131ae 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -780,7 +780,7 @@ def _addsub_offset_array(self, other, op): return self._from_sequence(res_values) @deprecate_kwarg(old_arg_name='n', new_arg_name='periods') - def shift(self, periods, freq=None): + def shift(self, periods, freq=None, fill_value=np.nan): """ Shift index by desired number of time frequency increments. @@ -810,9 +810,9 @@ def shift(self, periods, freq=None): Index.shift : Shift values of Index. PeriodIndex.shift : Shift values of PeriodIndex. """ - return self._time_shift(periods=periods, freq=freq) + return self._time_shift(periods=periods, freq=freq, fill_value=np.nan) - def _time_shift(self, periods, freq=None): + def _time_shift(self, periods, freq=None, fill_value=np.nan): """ Shift each value by `periods`. diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 2a8d58b8867b7..a6bc6226bda89 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -3867,9 +3867,9 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None, method=method) @Appender(_shared_docs['shift'] % _shared_doc_kwargs) - def shift(self, periods=1, freq=None, axis=0): + def shift(self, periods=1, freq=None, axis=0, fill_value=np.nan): return super(DataFrame, self).shift(periods=periods, freq=freq, - axis=axis) + axis=axis, fill_value=fill_value) def set_index(self, keys, drop=True, append=False, inplace=False, verify_integrity=False): diff --git a/pandas/core/generic.py b/pandas/core/generic.py index b3cb5c3be67f9..3eafc137c527f 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8868,15 +8868,15 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, """) @Appender(_shared_docs['shift'] % _shared_doc_kwargs) - def shift(self, periods=1, freq=None, axis=0): + def shift(self, periods=1, freq=None, axis=0, fill_value=np.nan): if periods == 0: return self.copy() block_axis = self._get_block_manager_axis(axis) if freq is None: - new_data = self._data.shift(periods=periods, axis=block_axis) + new_data = self._data.shift(periods=periods, axis=block_axis, fill_value=fill_value) else: - return self.tshift(periods, freq) + return self.tshift(periods, freq, fill_value=fill_value) return self._constructor(new_data).__finalize__(self) @@ -8916,7 +8916,7 @@ def slice_shift(self, periods=1, axis=0): return new_obj.__finalize__(self) - def tshift(self, periods=1, freq=None, axis=0): + def tshift(self, periods=1, freq=None, axis=0, fill_value=np.nan): """ Shift the time index, using the index's frequency if available. diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 9c2d4cd5729d2..e2c2c884c7987 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1260,12 +1260,12 @@ def diff(self, n, axis=1): new_values = algos.diff(self.values, n, axis=axis) return [self.make_block(values=new_values)] - def shift(self, periods, axis=0): + def shift(self, periods, axis=0, fill_value=np.nan): """ shift the block by periods, possibly upcast """ # convert integer to float if necessary. need to do a lot more than # that, handle boolean etc also - new_values, fill_value = maybe_upcast(self.values) + new_values, fill_value = maybe_upcast(self.values, fill_value) # make sure array sent to np.roll is c_contiguous f_ordered = new_values.flags.f_contiguous diff --git a/pandas/core/series.py b/pandas/core/series.py index 6d951a7a5228a..197c2f304700a 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -3714,8 +3714,8 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None, regex=regex, method=method) @Appender(generic._shared_docs['shift'] % _shared_doc_kwargs) - def shift(self, periods=1, freq=None, axis=0): - return super(Series, self).shift(periods=periods, freq=freq, axis=axis) + def shift(self, periods=1, freq=None, axis=0, fill_value=np.nan): + return super(Series, self).shift(periods=periods, freq=freq, axis=axis, fill_value=fill_value) def reindex_axis(self, labels, axis=0, **kwargs): """ diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index b9cf845ea47d7..a6c30aad46595 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -129,6 +129,37 @@ def test_shift2(self): idx = DatetimeIndex(['2000-01-01', '2000-01-02', '2000-01-04']) pytest.raises(NullFrequencyError, idx.shift, 1) + def test_shift_fill_value(self): + ts = Series(np.random.randn(5), + index=date_range('1/1/2000', periods=5, freq='H')) + + # fill_value should have no effect on shift with freq + result = ts.shift(1, freq='5T', fill_value=0) + exp_index = ts.index.shift(1, freq='5T') + tm.assert_index_equal(result.index, exp_index) + tm.assert_equal(result.iloc[0].value, ts.iloc[0].value) + + # check that fill value works + result = ts.shift(1, fill_value=0.0) + tm.assert_equal(result.iloc[0].value, 0.0) + tm.assert_equal(result.iloc[1].value, ts.iloc[0].value) + + result = ts.shift(2, fill_value=0.0) + tm.assert_equal(result.iloc[0].value, 0.0) + tm.assert_equal(result.iloc[1].value, 0.0) + tm.assert_equal(result.iloc[2].value, ts.iloc[0].value) + + df = DataFrame(np.random.randn(5), index=date_range('1/1/2000', periods=5, freq='H')) + + result = df.shift(1, fill_value=0.0) + tm.assert_equal(result.iloc[0, 0].value, 0.0) + tm.assert_equal(result.iloc[1, 0].value, df.iloc[0, 0].value) + + result = df.shift(2, fill_value=0.0) + tm.assert_equal(result.iloc[0, 0].value, 0.0) + tm.assert_equal(result.iloc[1, 0].value, 0.0) + tm.assert_equal(result.iloc[2, 0].value, df.iloc[0, 0].value) + def test_shift_dst(self): # GH 13926 dates = date_range('2016-11-06', freq='H', periods=10, tz='US/Eastern') From 6b4789d3386bfb7399729389dd407b3d9ef14093 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 6 Dec 2018 13:37:31 +0200 Subject: [PATCH 002/108] !U remove the data frame part form the time series --- pandas/tests/series/test_timeseries.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index a6c30aad46595..08790c806c3b1 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -149,16 +149,6 @@ def test_shift_fill_value(self): tm.assert_equal(result.iloc[1].value, 0.0) tm.assert_equal(result.iloc[2].value, ts.iloc[0].value) - df = DataFrame(np.random.randn(5), index=date_range('1/1/2000', periods=5, freq='H')) - - result = df.shift(1, fill_value=0.0) - tm.assert_equal(result.iloc[0, 0].value, 0.0) - tm.assert_equal(result.iloc[1, 0].value, df.iloc[0, 0].value) - - result = df.shift(2, fill_value=0.0) - tm.assert_equal(result.iloc[0, 0].value, 0.0) - tm.assert_equal(result.iloc[1, 0].value, 0.0) - tm.assert_equal(result.iloc[2, 0].value, df.iloc[0, 0].value) def test_shift_dst(self): # GH 13926 From 57c087e59056828ca1671355fddf4fbbe100f5da Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 6 Dec 2018 13:37:37 +0200 Subject: [PATCH 003/108] !U remove the data frame part form the time series --- pandas/tests/series/test_timeseries.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index 08790c806c3b1..68880adb08e14 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -149,7 +149,6 @@ def test_shift_fill_value(self): tm.assert_equal(result.iloc[1].value, 0.0) tm.assert_equal(result.iloc[2].value, ts.iloc[0].value) - def test_shift_dst(self): # GH 13926 dates = date_range('2016-11-06', freq='H', periods=10, tz='US/Eastern') From 1852ea66dc44c4498645207f4d442b5b9e3c9031 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 6 Dec 2018 13:37:51 +0200 Subject: [PATCH 004/108] !U fix formatting --- pandas/core/generic.py | 3 ++- pandas/core/series.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 3eafc137c527f..7f391d8040afe 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8874,7 +8874,8 @@ def shift(self, periods=1, freq=None, axis=0, fill_value=np.nan): block_axis = self._get_block_manager_axis(axis) if freq is None: - new_data = self._data.shift(periods=periods, axis=block_axis, fill_value=fill_value) + new_data = self._data.shift(periods=periods, axis=block_axis, + fill_value=fill_value) else: return self.tshift(periods, freq, fill_value=fill_value) diff --git a/pandas/core/series.py b/pandas/core/series.py index 197c2f304700a..2ec67afd65078 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -3715,7 +3715,8 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None, @Appender(generic._shared_docs['shift'] % _shared_doc_kwargs) def shift(self, periods=1, freq=None, axis=0, fill_value=np.nan): - return super(Series, self).shift(periods=periods, freq=freq, axis=axis, fill_value=fill_value) + return super(Series, self).shift(periods=periods, freq=freq, axis=axis, + fill_value=fill_value) def reindex_axis(self, labels, axis=0, **kwargs): """ From 34612719b635587494587f9ad142f1fb7857fbd6 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 6 Dec 2018 13:48:12 +0200 Subject: [PATCH 005/108] !U add test for data_frame --- pandas/tests/frame/test_timeseries.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pandas/tests/frame/test_timeseries.py b/pandas/tests/frame/test_timeseries.py index 52f0b30bf0f0c..f7b030e5c234f 100644 --- a/pandas/tests/frame/test_timeseries.py +++ b/pandas/tests/frame/test_timeseries.py @@ -320,6 +320,19 @@ def test_shift_categorical(self): xp = DataFrame({'one': s1.shift(1), 'two': s2.shift(1)}) assert_frame_equal(rs, xp) + def test_shift_fill_value(self): + df = DataFrame(np.random.randnint(5), index=date_range('1/1/2000', + periods=5, + freq='H')) + result = df.shift(1, fill_value=0) + tm.assert_equal(result.iloc[0, 0].value, 0) + tm.assert_equal(result.iloc[1, 0].value, df.iloc[0, 0].value) + + result = df.shift(2, fill_value=0) + tm.assert_equal(result.iloc[0, 0].value, 0) + tm.assert_equal(result.iloc[1, 0].value, 0) + tm.assert_equal(result.iloc[2, 0].value, df.iloc[0, 0].value) + def test_shift_empty(self): # Regression test for #8019 df = DataFrame({'foo': []}) From 8b5cedbf28c787f5db786eb23e30c3ec48b48577 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 6 Dec 2018 13:50:54 +0200 Subject: [PATCH 006/108] !U remove fill_value from tshift --- pandas/core/generic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 7f391d8040afe..0293f7a7afa57 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8877,7 +8877,7 @@ def shift(self, periods=1, freq=None, axis=0, fill_value=np.nan): new_data = self._data.shift(periods=periods, axis=block_axis, fill_value=fill_value) else: - return self.tshift(periods, freq, fill_value=fill_value) + return self.tshift(periods, freq) return self._constructor(new_data).__finalize__(self) @@ -8917,7 +8917,7 @@ def slice_shift(self, periods=1, axis=0): return new_obj.__finalize__(self) - def tshift(self, periods=1, freq=None, axis=0, fill_value=np.nan): + def tshift(self, periods=1, freq=None, axis=0): """ Shift the time index, using the index's frequency if available. From 27226fa148103b6fa5a27f974f14d7a1a616450c Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 6 Dec 2018 14:04:25 +0200 Subject: [PATCH 007/108] !U remove unrelevant change --- pandas/core/arrays/datetimelike.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index a77faabd131ae..45eec41e498d1 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -780,7 +780,7 @@ def _addsub_offset_array(self, other, op): return self._from_sequence(res_values) @deprecate_kwarg(old_arg_name='n', new_arg_name='periods') - def shift(self, periods, freq=None, fill_value=np.nan): + def shift(self, periods, freq=None): """ Shift index by desired number of time frequency increments. @@ -810,9 +810,9 @@ def shift(self, periods, freq=None, fill_value=np.nan): Index.shift : Shift values of Index. PeriodIndex.shift : Shift values of PeriodIndex. """ - return self._time_shift(periods=periods, freq=freq, fill_value=np.nan) + return self._time_shift(periods=periods, freq=freq) - def _time_shift(self, periods, freq=None, fill_value=np.nan): + def _time_shift(self, periods, freq=None): """ Shift each value by `periods`. From 29b8a6effd5d3efe06725bf09b649485a27614d4 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 6 Dec 2018 14:32:51 +0200 Subject: [PATCH 008/108] !U add doc for new fill_value argument for shift method --- pandas/core/generic.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 0293f7a7afa57..7d85d368538bc 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8829,7 +8829,10 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, data is not realigned. That is, use `freq` if you would like to extend the index when shifting and preserve the original data. axis : {0 or 'index', 1 or 'columns', None}, default None - Shift direction. + Shift direction. + fill_value : None or value, default None (NaN). + Filling the empty space after shift with value provided by + the user instead of NaN Returns ------- @@ -8865,6 +8868,14 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, 2 NaN 15.0 18.0 3 NaN 30.0 33.0 4 NaN 45.0 48.0 + + >>> df.shift(periods=3, fill_value=0.0) + Col1 Col2 Col3 + 0 0.0 0.0 0.0 + 1 0.0 0.0 0.0 + 2 0.0 0.0 0.0 + 3 10.0 13.0 17.0 + 4 20.0 23.0 27.0 """) @Appender(_shared_docs['shift'] % _shared_doc_kwargs) From cf6b2dd9b7e716747dd2a6159a68e09295a28abe Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 6 Dec 2018 14:35:04 +0200 Subject: [PATCH 009/108] !U add GH number --- pandas/tests/frame/test_timeseries.py | 1 + pandas/tests/series/test_timeseries.py | 1 + 2 files changed, 2 insertions(+) diff --git a/pandas/tests/frame/test_timeseries.py b/pandas/tests/frame/test_timeseries.py index f7b030e5c234f..d9368de3de1de 100644 --- a/pandas/tests/frame/test_timeseries.py +++ b/pandas/tests/frame/test_timeseries.py @@ -321,6 +321,7 @@ def test_shift_categorical(self): assert_frame_equal(rs, xp) def test_shift_fill_value(self): + # GH #24128 df = DataFrame(np.random.randnint(5), index=date_range('1/1/2000', periods=5, freq='H')) diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index 68880adb08e14..700cc9d0af44c 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -130,6 +130,7 @@ def test_shift2(self): pytest.raises(NullFrequencyError, idx.shift, 1) def test_shift_fill_value(self): + # GH #24128 ts = Series(np.random.randn(5), index=date_range('1/1/2000', periods=5, freq='H')) From 9f9962c1793569fd5f9620149277a6d5358ee223 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 6 Dec 2018 14:43:17 +0200 Subject: [PATCH 010/108] !U add versionated tag --- pandas/core/generic.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 7d85d368538bc..415fdb643edae 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8829,10 +8829,13 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, data is not realigned. That is, use `freq` if you would like to extend the index when shifting and preserve the original data. axis : {0 or 'index', 1 or 'columns', None}, default None - Shift direction. - fill_value : None or value, default None (NaN). - Filling the empty space after shift with value provided by - the user instead of NaN + Shift direction. + + .. versionchanged:: 0.24.0 + + fill_value : None or value, default None (NaN). + Filling the empty space after shift with value provided by + the user instead of NaN Returns ------- @@ -8869,13 +8872,15 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, 3 NaN 30.0 33.0 4 NaN 45.0 48.0 - >>> df.shift(periods=3, fill_value=0.0) - Col1 Col2 Col3 - 0 0.0 0.0 0.0 - 1 0.0 0.0 0.0 - 2 0.0 0.0 0.0 - 3 10.0 13.0 17.0 - 4 20.0 23.0 27.0 + .. versionchanged:: 0.24.0 + + >>> df.shift(periods=3, fill_value=0.0) + Col1 Col2 Col3 + 0 0.0 0.0 0.0 + 1 0.0 0.0 0.0 + 2 0.0 0.0 0.0 + 3 10.0 13.0 17.0 + 4 20.0 23.0 27.0 """) @Appender(_shared_docs['shift'] % _shared_doc_kwargs) From 4c7b7629a03bdf98421c5bdad81c4e73309402af Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 6 Dec 2018 15:20:37 +0200 Subject: [PATCH 011/108] !U add fill_value to the group by interface --- pandas/core/groupby/groupby.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 253860d83f49e..0255de90d7961 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -1993,7 +1993,7 @@ def _get_cythonized_result(self, how, grouper, aggregate=False, @Substitution(name='groupby') @Appender(_doc_template) - def shift(self, periods=1, freq=None, axis=0): + def shift(self, periods=1, freq=None, axis=0, fill_value=np.nan): """ Shift each group by periods observations. @@ -2003,10 +2003,11 @@ def shift(self, periods=1, freq=None, axis=0): number of periods to shift freq : frequency string axis : axis to shift, default 0 + fill_value : None or value, default None (NaN). """ if freq is not None or axis != 0: - return self.apply(lambda x: x.shift(periods, freq, axis)) + return self.apply(lambda x: x.shift(periods, freq, axis, fill_value)) return self._get_cythonized_result('group_shift_indexer', self.grouper, cython_dtype=np.int64, From b36ca432ff999df2931006cb6eafe147e40c713b Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 6 Dec 2018 15:31:48 +0200 Subject: [PATCH 012/108] !U replace np.nan to None --- pandas/core/generic.py | 2 +- pandas/core/groupby/groupby.py | 2 +- pandas/core/internals/blocks.py | 2 +- pandas/core/series.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 415fdb643edae..35282f9e08b4f 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8884,7 +8884,7 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, """) @Appender(_shared_docs['shift'] % _shared_doc_kwargs) - def shift(self, periods=1, freq=None, axis=0, fill_value=np.nan): + def shift(self, periods=1, freq=None, axis=0, fill_value=None): if periods == 0: return self.copy() diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 0255de90d7961..041d4a787f19d 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -1993,7 +1993,7 @@ def _get_cythonized_result(self, how, grouper, aggregate=False, @Substitution(name='groupby') @Appender(_doc_template) - def shift(self, periods=1, freq=None, axis=0, fill_value=np.nan): + def shift(self, periods=1, freq=None, axis=0, fill_value=None): """ Shift each group by periods observations. diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index e2c2c884c7987..eca98ac2edb53 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1260,7 +1260,7 @@ def diff(self, n, axis=1): new_values = algos.diff(self.values, n, axis=axis) return [self.make_block(values=new_values)] - def shift(self, periods, axis=0, fill_value=np.nan): + def shift(self, periods, axis=0, fill_value=None): """ shift the block by periods, possibly upcast """ # convert integer to float if necessary. need to do a lot more than diff --git a/pandas/core/series.py b/pandas/core/series.py index 2ec67afd65078..5c0e14787e7e0 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -3714,7 +3714,7 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None, regex=regex, method=method) @Appender(generic._shared_docs['shift'] % _shared_doc_kwargs) - def shift(self, periods=1, freq=None, axis=0, fill_value=np.nan): + def shift(self, periods=1, freq=None, axis=0, fill_value=None): return super(Series, self).shift(periods=periods, freq=freq, axis=axis, fill_value=fill_value) From a36e7c70b542a86ed3cba94fbadd3f2b19b8241b Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 6 Dec 2018 15:33:04 +0200 Subject: [PATCH 013/108] !U replace np.nan to None --- pandas/core/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index a6bc6226bda89..0834319c66644 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -3867,7 +3867,7 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None, method=method) @Appender(_shared_docs['shift'] % _shared_doc_kwargs) - def shift(self, periods=1, freq=None, axis=0, fill_value=np.nan): + def shift(self, periods=1, freq=None, axis=0, fill_value=None): return super(DataFrame, self).shift(periods=periods, freq=freq, axis=axis, fill_value=fill_value) From 4c2ec2c075cc3f836d47fc2b325c2cd79bf21125 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Fri, 7 Dec 2018 02:39:50 +0200 Subject: [PATCH 014/108] !U add fill_value to the locations where it was missing --- pandas/core/arrays/base.py | 9 +++++++-- pandas/core/arrays/categorical.py | 8 +++++--- pandas/core/arrays/period.py | 4 ++-- pandas/core/arrays/sparse.py | 6 ++++-- pandas/core/internals/blocks.py | 12 +++++++----- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index 9c6aa4a12923f..028f7a0e87d49 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -445,7 +445,7 @@ def dropna(self): return self[~self.isna()] - def shift(self, periods=1): + def shift(self, periods=1, fill_value=None): # type: (int) -> ExtensionArray """ Shift values by desired number. @@ -461,6 +461,8 @@ def shift(self, periods=1): The number of periods to shift. Negative values are allowed for shifting backwards. + .. versionadded:: 0.24.0 + fill_value : None or value, default None (NaN) Returns ------- shifted : ExtensionArray @@ -469,7 +471,10 @@ def shift(self, periods=1): # stored in an instance of your ExtensionArray with `self.dtype`. if periods == 0: return self.copy() - empty = self._from_sequence([self.dtype.na_value] * abs(periods), + if fill_value is None: + fill_value = self.dtype.na_value + + empty = self._from_sequence([fill_value] * abs(periods), dtype=self.dtype) if periods > 0: a = empty diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 938ca53b5fdce..478cdf23f474f 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -1255,7 +1255,7 @@ def shape(self): return tuple([len(self._codes)]) - def shift(self, periods): + def shift(self, periods, fill_value=None): """ Shift Categorical by desired number of periods. @@ -1275,10 +1275,12 @@ def shift(self, periods): raise NotImplementedError("Categorical with ndim > 1.") if np.prod(codes.shape) and (periods != 0): codes = np.roll(codes, ensure_platform_int(periods), axis=0) + if fill_value is None: + fill_value = -1 if periods > 0: - codes[:periods] = -1 + codes[:periods] = fill_value else: - codes[periods:] = -1 + codes[periods:] = fill_value return self.from_codes(codes, categories=self.categories, ordered=self.ordered) diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index d9dde1c699761..43372fd2e9fb0 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -457,7 +457,7 @@ def value_counts(self, dropna=False): # -------------------------------------------------------------------- - def shift(self, periods=1): + def shift(self, periods=1, fill_value=None): """ Shift values by desired number. @@ -479,7 +479,7 @@ def shift(self, periods=1): # TODO(DatetimeArray): remove # The semantics for Index.shift differ from EA.shift # then just call super. - return ExtensionArray.shift(self, periods) + return ExtensionArray.shift(self, periods, fill_value=fill_value) def _time_shift(self, n, freq=None): """ diff --git a/pandas/core/arrays/sparse.py b/pandas/core/arrays/sparse.py index 134466d769ada..92c3aaa4a418f 100644 --- a/pandas/core/arrays/sparse.py +++ b/pandas/core/arrays/sparse.py @@ -887,7 +887,7 @@ def fillna(self, value=None, method=None, limit=None): return self._simple_new(new_values, self._sparse_index, new_dtype) - def shift(self, periods=1): + def shift(self, periods=1, fill_value=None): if periods == 0: return self.copy() @@ -900,7 +900,9 @@ def shift(self, periods=1): else: arr = self - empty = self._from_sequence([self.dtype.na_value] * abs(periods), + if fill_value is None: + fill_value = self.dtype.na_value + empty = self._from_sequence([fill_value] * abs(periods), dtype=arr.dtype) if periods > 0: a = empty diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index eca98ac2edb53..0bef787a357a7 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1955,7 +1955,7 @@ def interpolate(self, method='pad', axis=0, inplace=False, limit=None, limit=limit), placement=self.mgr_locs) - def shift(self, periods, axis=0): + def shift(self, periods, axis=0, fill_value=None): """ Shift the block by `periods`. @@ -1963,7 +1963,7 @@ def shift(self, periods, axis=0): ExtensionBlock. """ # type: (int, Optional[BlockPlacement]) -> List[ExtensionBlock] - return [self.make_block_same_class(self.values.shift(periods=periods), + return [self.make_block_same_class(self.values.shift(periods=periods, fill_value=fill_value), placement=self.mgr_locs, ndim=self.ndim)] @@ -2933,7 +2933,7 @@ def _try_coerce_result(self, result): def _box_func(self): return lambda x: tslibs.Timestamp(x, tz=self.dtype.tz) - def shift(self, periods, axis=0): + def shift(self, periods, axis=0, fill_value=None): """ shift the block by periods """ # think about moving this to the DatetimeIndex. This is a non-freq @@ -2948,10 +2948,12 @@ def shift(self, periods, axis=0): new_values = self.values.asi8.take(indexer) + if fill_value is None: + fill_value = tslibs.iNaT if periods > 0: - new_values[:periods] = tslibs.iNaT + new_values[:periods] = fill_value else: - new_values[periods:] = tslibs.iNaT + new_values[periods:] = fill_value new_values = self.values._shallow_copy(new_values) return [self.make_block_same_class(new_values, From fbf3d737a9b8c3e060c3e4168486127274cad0ce Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Fri, 7 Dec 2018 03:55:28 +0200 Subject: [PATCH 015/108] !U fix series test --- pandas/tests/series/test_timeseries.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index 700cc9d0af44c..a6de02f8aafac 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -138,17 +138,17 @@ def test_shift_fill_value(self): result = ts.shift(1, freq='5T', fill_value=0) exp_index = ts.index.shift(1, freq='5T') tm.assert_index_equal(result.index, exp_index) - tm.assert_equal(result.iloc[0].value, ts.iloc[0].value) + tm.assert_equal(result.iloc[0], ts.iloc[0]) # check that fill value works result = ts.shift(1, fill_value=0.0) - tm.assert_equal(result.iloc[0].value, 0.0) - tm.assert_equal(result.iloc[1].value, ts.iloc[0].value) + tm.assert_equal(result.iloc[0], 0.0) + tm.assert_equal(result.iloc[1], ts.iloc[0]) result = ts.shift(2, fill_value=0.0) - tm.assert_equal(result.iloc[0].value, 0.0) - tm.assert_equal(result.iloc[1].value, 0.0) - tm.assert_equal(result.iloc[2].value, ts.iloc[0].value) + tm.assert_equal(result.iloc[0], 0.0) + tm.assert_equal(result.iloc[1], 0.0) + tm.assert_equal(result.iloc[2], ts.iloc[0]) def test_shift_dst(self): # GH 13926 From bb722a60192aeb67d9829496668eea3bc92c4ac4 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Fri, 7 Dec 2018 03:56:27 +0200 Subject: [PATCH 016/108] !U fix method name and values comparison for the new test --- pandas/tests/frame/test_timeseries.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pandas/tests/frame/test_timeseries.py b/pandas/tests/frame/test_timeseries.py index d9368de3de1de..ef13e1884cb11 100644 --- a/pandas/tests/frame/test_timeseries.py +++ b/pandas/tests/frame/test_timeseries.py @@ -322,17 +322,17 @@ def test_shift_categorical(self): def test_shift_fill_value(self): # GH #24128 - df = DataFrame(np.random.randnint(5), index=date_range('1/1/2000', + df = DataFrame(np.random.randint(5), index=date_range('1/1/2000', periods=5, freq='H')) result = df.shift(1, fill_value=0) - tm.assert_equal(result.iloc[0, 0].value, 0) - tm.assert_equal(result.iloc[1, 0].value, df.iloc[0, 0].value) + tm.assert_equal(result.iloc[0, 0], 0) + tm.assert_equal(result.iloc[1, 0], df.iloc[0, 0]) result = df.shift(2, fill_value=0) - tm.assert_equal(result.iloc[0, 0].value, 0) - tm.assert_equal(result.iloc[1, 0].value, 0) - tm.assert_equal(result.iloc[2, 0].value, df.iloc[0, 0].value) + tm.assert_equal(result.iloc[0, 0], 0) + tm.assert_equal(result.iloc[1, 0], 0) + tm.assert_equal(result.iloc[2, 0], df.iloc[0, 0]) def test_shift_empty(self): # Regression test for #8019 From 1b1fdc2031504b7ee64669257ad744db3f7fccba Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Fri, 7 Dec 2018 19:40:44 +0200 Subject: [PATCH 017/108] !U fix dataframe constructor --- pandas/tests/frame/test_timeseries.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pandas/tests/frame/test_timeseries.py b/pandas/tests/frame/test_timeseries.py index ef13e1884cb11..4fc8dd5f4a862 100644 --- a/pandas/tests/frame/test_timeseries.py +++ b/pandas/tests/frame/test_timeseries.py @@ -322,9 +322,8 @@ def test_shift_categorical(self): def test_shift_fill_value(self): # GH #24128 - df = DataFrame(np.random.randint(5), index=date_range('1/1/2000', - periods=5, - freq='H')) + df = DataFrame(np.random.randint(5, size=5), + index=date_range('1/1/2000', periods=5, freq='H')) result = df.shift(1, fill_value=0) tm.assert_equal(result.iloc[0, 0], 0) tm.assert_equal(result.iloc[1, 0], df.iloc[0, 0]) From c3f462ceca874d5304db56ec2e93eeafe8dfcc7f Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sat, 8 Dec 2018 00:00:56 +0200 Subject: [PATCH 018/108] !U change the assert method used for new tests --- pandas/tests/frame/test_timeseries.py | 10 +++++----- pandas/tests/series/test_timeseries.py | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pandas/tests/frame/test_timeseries.py b/pandas/tests/frame/test_timeseries.py index 4fc8dd5f4a862..1fb3c0d402a26 100644 --- a/pandas/tests/frame/test_timeseries.py +++ b/pandas/tests/frame/test_timeseries.py @@ -325,13 +325,13 @@ def test_shift_fill_value(self): df = DataFrame(np.random.randint(5, size=5), index=date_range('1/1/2000', periods=5, freq='H')) result = df.shift(1, fill_value=0) - tm.assert_equal(result.iloc[0, 0], 0) - tm.assert_equal(result.iloc[1, 0], df.iloc[0, 0]) + np.testing.assert_equal(result.iloc[0, 0], 0) + np.testing.assert_equal(result.iloc[1, 0], df.iloc[0, 0]) result = df.shift(2, fill_value=0) - tm.assert_equal(result.iloc[0, 0], 0) - tm.assert_equal(result.iloc[1, 0], 0) - tm.assert_equal(result.iloc[2, 0], df.iloc[0, 0]) + np.testing.assert_equal(result.iloc[0, 0], 0) + np.testing.assert_equal(result.iloc[1, 0], 0) + np.testing.assert_equal(result.iloc[2, 0], df.iloc[0, 0]) def test_shift_empty(self): # Regression test for #8019 diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index a6de02f8aafac..fc1ab66c47ed2 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -138,17 +138,17 @@ def test_shift_fill_value(self): result = ts.shift(1, freq='5T', fill_value=0) exp_index = ts.index.shift(1, freq='5T') tm.assert_index_equal(result.index, exp_index) - tm.assert_equal(result.iloc[0], ts.iloc[0]) + np.testing.assert_equal(result.iloc[0], ts.iloc[0]) # check that fill value works result = ts.shift(1, fill_value=0.0) - tm.assert_equal(result.iloc[0], 0.0) - tm.assert_equal(result.iloc[1], ts.iloc[0]) + np.testing.assert_equal(result.iloc[0], 0.0) + np.testing.assert_equal(result.iloc[1], ts.iloc[0]) result = ts.shift(2, fill_value=0.0) - tm.assert_equal(result.iloc[0], 0.0) - tm.assert_equal(result.iloc[1], 0.0) - tm.assert_equal(result.iloc[2], ts.iloc[0]) + np.testing.assert_equal(result.iloc[0], 0.0) + np.testing.assert_equal(result.iloc[1], 0.0) + np.testing.assert_equal(result.iloc[2], ts.iloc[0]) def test_shift_dst(self): # GH 13926 From e44b514c8edafb7e6aa186132e5da0adaefcd5ea Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sat, 8 Dec 2018 13:09:15 +0200 Subject: [PATCH 019/108] !U change formatting and doc scripts --- pandas/core/arrays/base.py | 5 +++-- pandas/core/arrays/categorical.py | 2 ++ pandas/core/arrays/period.py | 2 ++ pandas/core/generic.py | 27 +++++++++++++-------------- pandas/core/internals/blocks.py | 8 +++++--- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index 028f7a0e87d49..df910dd754e8c 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -461,8 +461,9 @@ def shift(self, periods=1, fill_value=None): The number of periods to shift. Negative values are allowed for shifting backwards. - .. versionadded:: 0.24.0 - fill_value : None or value, default None (NaN) + fill_value : None or value, default None (NaN) + .. versionadded:: 0.24.0 + Returns ------- shifted : ExtensionArray diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 478cdf23f474f..bae753b8e94ed 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -1263,6 +1263,8 @@ def shift(self, periods, fill_value=None): ---------- periods : int Number of periods to move, can be positive or negative + fill_value : None or value, default None (NaN) + .. versionadded:: 0.24.0 Returns ------- diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 43372fd2e9fb0..5a819d11080db 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -471,6 +471,8 @@ def shift(self, periods=1, fill_value=None): periods : int, default 1 The number of periods to shift. Negative values are allowed for shifting backwards. + fill_value : None or value, default None (NaT) + .. versionadded:: 0.24.0 Returns ------- diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 35282f9e08b4f..6b9f08347da34 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8830,12 +8830,12 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, extend the index when shifting and preserve the original data. axis : {0 or 'index', 1 or 'columns', None}, default None Shift direction. + fill_value : object, optional + the scalar value to use for newly introduced missing values. + the default depends on the dtype of `self`. for numeric data, + ``np.nan`` is used. for datelike, ``pandas.nat`` is used. - .. versionchanged:: 0.24.0 - - fill_value : None or value, default None (NaN). - Filling the empty space after shift with value provided by - the user instead of NaN + .. versionchanged:: 0.24.0 Returns ------- @@ -8872,15 +8872,14 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, 3 NaN 30.0 33.0 4 NaN 45.0 48.0 - .. versionchanged:: 0.24.0 - - >>> df.shift(periods=3, fill_value=0.0) - Col1 Col2 Col3 - 0 0.0 0.0 0.0 - 1 0.0 0.0 0.0 - 2 0.0 0.0 0.0 - 3 10.0 13.0 17.0 - 4 20.0 23.0 27.0 + >>> df.shift(periods=3, fill_value=0.0) + Col1 Col2 Col3 + 0 0.0 0.0 0.0 + 1 0.0 0.0 0.0 + 2 0.0 0.0 0.0 + 3 10.0 13.0 17.0 + 4 20.0 23.0 27.0 + """) @Appender(_shared_docs['shift'] % _shared_doc_kwargs) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 0bef787a357a7..3881aae9287d0 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1963,9 +1963,11 @@ def shift(self, periods, axis=0, fill_value=None): ExtensionBlock. """ # type: (int, Optional[BlockPlacement]) -> List[ExtensionBlock] - return [self.make_block_same_class(self.values.shift(periods=periods, fill_value=fill_value), - placement=self.mgr_locs, - ndim=self.ndim)] + return [ + self.make_block_same_class(self.values.shift(periods=periods, + fill_value=fill_value), + placement=self.mgr_locs, ndim=self.ndim) + ] @property def _ftype(self): From 38f621caafd81c75fb2c9d6f03fab8efae067dc3 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sat, 8 Dec 2018 13:15:27 +0200 Subject: [PATCH 020/108] !U add doc strings --- pandas/core/arrays/base.py | 5 ++++- pandas/core/arrays/categorical.py | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index df910dd754e8c..b614f4521af27 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -461,7 +461,10 @@ def shift(self, periods=1, fill_value=None): The number of periods to shift. Negative values are allowed for shifting backwards. - fill_value : None or value, default None (NaN) + fill_value : object, optional + The scalar value to use for newly introduced missing values. + The default is ``self.dtype.na_value``. + .. versionadded:: 0.24.0 Returns diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index bae753b8e94ed..6d4846cf25698 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -1263,7 +1263,10 @@ def shift(self, periods, fill_value=None): ---------- periods : int Number of periods to move, can be positive or negative - fill_value : None or value, default None (NaN) + fill_value : object, optional + The scalar value to use for newly introduced missing values. + The default is ``-1``. + .. versionadded:: 0.24.0 Returns From d9d9fdb06bba706c9b544d8b867ecce57a149b16 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sat, 8 Dec 2018 13:51:14 +0200 Subject: [PATCH 021/108] !U add check for fill_value present in the categorical categories --- pandas/core/arrays/categorical.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 6d4846cf25698..25b6fb1c59204 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -1282,6 +1282,10 @@ def shift(self, periods, fill_value=None): codes = np.roll(codes, ensure_platform_int(periods), axis=0) if fill_value is None: fill_value = -1 + elif fill_value in self.categories: + fill_value = self.categories.get_loc(fill_value) + else: + raise ValueError("'fill_value={}' is not present in this Categorical's categories".format(fill_value)) if periods > 0: codes[:periods] = fill_value else: From cc6f370fee500397e384e58ff6f804cadb7da871 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 02:08:52 +0200 Subject: [PATCH 022/108] !U change test for frame --- pandas/tests/frame/test_timeseries.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pandas/tests/frame/test_timeseries.py b/pandas/tests/frame/test_timeseries.py index 1fb3c0d402a26..346b56c9a9d69 100644 --- a/pandas/tests/frame/test_timeseries.py +++ b/pandas/tests/frame/test_timeseries.py @@ -322,16 +322,17 @@ def test_shift_categorical(self): def test_shift_fill_value(self): # GH #24128 - df = DataFrame(np.random.randint(5, size=5), + df = DataFrame([1, 2, 3, 4, 5], + index=date_range('1/1/2000', periods=5, freq='H')) + expected = DataFrame([0, 1, 2, 3, 4], index=date_range('1/1/2000', periods=5, freq='H')) result = df.shift(1, fill_value=0) - np.testing.assert_equal(result.iloc[0, 0], 0) - np.testing.assert_equal(result.iloc[1, 0], df.iloc[0, 0]) + assert_frame_equal(result, expected) + expected = DataFrame([0, 0, 1, 2, 3], + index=date_range('1/1/2000', periods=5, freq='H')) result = df.shift(2, fill_value=0) - np.testing.assert_equal(result.iloc[0, 0], 0) - np.testing.assert_equal(result.iloc[1, 0], 0) - np.testing.assert_equal(result.iloc[2, 0], df.iloc[0, 0]) + assert_frame_equal(result, expected) def test_shift_empty(self): # Regression test for #8019 From 36194100428c0a28fe3d142f1b3fc65b71850d76 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 02:14:21 +0200 Subject: [PATCH 023/108] !U change test for series shift with fill value to avoid formatting error --- pandas/tests/series/test_timeseries.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index fc1ab66c47ed2..f7bd5e7936a30 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -131,24 +131,25 @@ def test_shift2(self): def test_shift_fill_value(self): # GH #24128 - ts = Series(np.random.randn(5), + ts = Series([1.0, 2.0, 3.0, 4.0, 5.0], index=date_range('1/1/2000', periods=5, freq='H')) # fill_value should have no effect on shift with freq result = ts.shift(1, freq='5T', fill_value=0) exp_index = ts.index.shift(1, freq='5T') tm.assert_index_equal(result.index, exp_index) - np.testing.assert_equal(result.iloc[0], ts.iloc[0]) + tm.assert_numpy_array_equal(result.values, ts.values) + expected = Series([0.0, 1.0, 2.0, 3.0, 4.0], + index=date_range('1/1/2000', periods=5, freq='H')) # check that fill value works result = ts.shift(1, fill_value=0.0) - np.testing.assert_equal(result.iloc[0], 0.0) - np.testing.assert_equal(result.iloc[1], ts.iloc[0]) + tm.assert_series_equal(result, expected) + expected = Series([0.0, 0.0, 1.0, 2.0, 3.0], + index=date_range('1/1/2000', periods=5, freq='H')) result = ts.shift(2, fill_value=0.0) - np.testing.assert_equal(result.iloc[0], 0.0) - np.testing.assert_equal(result.iloc[1], 0.0) - np.testing.assert_equal(result.iloc[2], ts.iloc[0]) + tm.assert_series_equal(result, expected) def test_shift_dst(self): # GH 13926 From ca5ba24b2adbd0e547c98cbadaed4b5283e63613 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 03:23:20 +0200 Subject: [PATCH 024/108] !U remove dot --- pandas/core/groupby/groupby.py | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 041d4a787f19d..327ab4a788b6d 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -8,38 +8,36 @@ class providing the base-class of operations. """ import collections -from contextlib import contextmanager import datetime -from functools import partial, wraps import types import warnings +from contextlib import contextmanager +from functools import partial, wraps import numpy as np -from pandas._libs import Timestamp, groupby as libgroupby import pandas.compat as compat +import pandas.core.algorithms as algorithms +import pandas.core.common as com +from pandas._libs import Timestamp, groupby as libgroupby from pandas.compat import callable, range, set_function_name, zip from pandas.compat.numpy import function as nv -from pandas.errors import AbstractMethodError -from pandas.util._decorators import Appender, Substitution, cache_readonly -from pandas.util._validators import validate_kwargs - +from pandas.core.base import ( + DataError, GroupByError, PandasObject, SelectionMixin, SpecificationError) +from pandas.core.config import option_context from pandas.core.dtypes.cast import maybe_downcast_to_dtype from pandas.core.dtypes.common import ( ensure_float, is_extension_array_dtype, is_numeric_dtype, is_scalar) from pandas.core.dtypes.missing import isna, notna - -import pandas.core.algorithms as algorithms -from pandas.core.base import ( - DataError, GroupByError, PandasObject, SelectionMixin, SpecificationError) -import pandas.core.common as com -from pandas.core.config import option_context from pandas.core.frame import DataFrame from pandas.core.generic import NDFrame from pandas.core.groupby import base from pandas.core.index import Index, MultiIndex from pandas.core.series import Series from pandas.core.sorting import get_group_index_sorter +from pandas.errors import AbstractMethodError +from pandas.util._decorators import Appender, Substitution, cache_readonly +from pandas.util._validators import validate_kwargs _doc_template = """ See Also @@ -2003,7 +2001,7 @@ def shift(self, periods=1, freq=None, axis=0, fill_value=None): number of periods to shift freq : frequency string axis : axis to shift, default 0 - fill_value : None or value, default None (NaN). + fill_value : None or value, default None (NaN) """ if freq is not None or axis != 0: From c195a136b7079e284417dcfa7f263697f1fbbd61 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 03:31:30 +0200 Subject: [PATCH 025/108] !U remove empty line --- pandas/core/generic.py | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 6b9f08347da34..c569a75347adf 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -9,17 +9,18 @@ import numpy as np -from pandas._libs import Timestamp, iNaT, properties +import pandas as pd import pandas.compat as compat +import pandas.core.algorithms as algos +import pandas.core.common as com +import pandas.core.indexing as indexing +from pandas._libs import Timestamp, iNaT, properties from pandas.compat import ( cPickle as pkl, isidentifier, lrange, lzip, map, set_function_name, string_types, to_str, zip) from pandas.compat.numpy import function as nv -from pandas.errors import AbstractMethodError -from pandas.util._decorators import ( - Appender, Substitution, rewrite_axis_style_signature) -from pandas.util._validators import validate_bool_kwarg, validate_fillna_kwargs - +from pandas.core import config, missing, nanops +from pandas.core.base import PandasObject, SelectionMixin from pandas.core.dtypes.cast import maybe_promote, maybe_upcast_putmask from pandas.core.dtypes.common import ( ensure_int64, ensure_object, is_bool, is_bool_dtype, @@ -30,23 +31,19 @@ from pandas.core.dtypes.generic import ABCDataFrame, ABCPanel, ABCSeries from pandas.core.dtypes.inference import is_hashable from pandas.core.dtypes.missing import isna, notna - -import pandas as pd -from pandas.core import config, missing, nanops -import pandas.core.algorithms as algos -from pandas.core.base import PandasObject, SelectionMixin -import pandas.core.common as com from pandas.core.index import ( Index, InvalidIndexError, MultiIndex, RangeIndex, ensure_index) from pandas.core.indexes.datetimes import DatetimeIndex from pandas.core.indexes.period import Period, PeriodIndex -import pandas.core.indexing as indexing from pandas.core.internals import BlockManager from pandas.core.ops import _align_method_FRAME - +from pandas.errors import AbstractMethodError from pandas.io.formats.format import DataFrameFormatter, format_percentiles from pandas.io.formats.printing import pprint_thing from pandas.tseries.frequencies import to_offset +from pandas.util._decorators import ( + Appender, Substitution, rewrite_axis_style_signature) +from pandas.util._validators import validate_bool_kwarg, validate_fillna_kwargs # goal is to be able to define the docs close to function, while still being # able to share @@ -8879,7 +8876,6 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, 2 0.0 0.0 0.0 3 10.0 13.0 17.0 4 20.0 23.0 27.0 - """) @Appender(_shared_docs['shift'] % _shared_doc_kwargs) From af90a0033ee4bc6780e96e292217d120e80b8be6 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 03:33:07 +0200 Subject: [PATCH 026/108] !U fix the line lenght --- pandas/core/internals/blocks.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 3881aae9287d0..4c9ac76c6ed4a 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1,18 +1,22 @@ # -*- coding: utf-8 -*- -from datetime import date, datetime, timedelta import functools import inspect import re import warnings +from datetime import date, datetime, timedelta import numpy as np +import pandas.compat as compat +import pandas.core.algorithms as algos +import pandas.core.common as com +import pandas.core.dtypes.concat as _concat +import pandas.core.missing as missing from pandas._libs import internals as libinternals, lib, tslib, tslibs from pandas._libs.tslibs import Timedelta, conversion -import pandas.compat as compat from pandas.compat import range, zip -from pandas.util._validators import validate_bool_kwarg - +from pandas.core.arrays import Categorical, ExtensionArray +from pandas.core.base import PandasObject from pandas.core.dtypes.cast import ( astype_nansafe, find_common_type, infer_dtype_from, infer_dtype_from_scalar, maybe_convert_objects, maybe_downcast_to_dtype, @@ -24,24 +28,17 @@ is_float_dtype, is_integer, is_integer_dtype, is_list_like, is_numeric_v_string_like, is_object_dtype, is_re, is_re_compilable, is_sparse, is_timedelta64_dtype, pandas_dtype) -import pandas.core.dtypes.concat as _concat from pandas.core.dtypes.dtypes import ( CategoricalDtype, DatetimeTZDtype, ExtensionDtype, PandasExtensionDtype) from pandas.core.dtypes.generic import ( ABCDatetimeIndex, ABCExtensionArray, ABCIndexClass, ABCSeries) from pandas.core.dtypes.missing import ( _isna_compat, array_equivalent, is_null_datelike_scalar, isna, notna) - -import pandas.core.algorithms as algos -from pandas.core.arrays import Categorical, ExtensionArray -from pandas.core.base import PandasObject -import pandas.core.common as com from pandas.core.indexes.datetimes import DatetimeIndex from pandas.core.indexes.timedeltas import TimedeltaIndex from pandas.core.indexing import check_setitem_lengths -import pandas.core.missing as missing - from pandas.io.formats.printing import pprint_thing +from pandas.util._validators import validate_bool_kwarg class Block(PandasObject): @@ -1964,9 +1961,9 @@ def shift(self, periods, axis=0, fill_value=None): """ # type: (int, Optional[BlockPlacement]) -> List[ExtensionBlock] return [ - self.make_block_same_class(self.values.shift(periods=periods, - fill_value=fill_value), - placement=self.mgr_locs, ndim=self.ndim) + self.make_block_same_class( + self.values.shift(periods=periods, fill_value=fill_value), + placement=self.mgr_locs, ndim=self.ndim) ] @property From 2f9b7126cd74414fb262703af8236a4cad878f19 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 03:33:58 +0200 Subject: [PATCH 027/108] !U format the exception message --- pandas/core/arrays/categorical.py | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 25b6fb1c59204..aa2ba5519435c 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -5,14 +5,16 @@ import numpy as np -from pandas._libs import algos as libalgos, lib import pandas.compat as compat +import pandas.core.algorithms as algorithms +import pandas.core.common as com +from pandas._libs import algos as libalgos, lib from pandas.compat import lzip, u from pandas.compat.numpy import function as nv -from pandas.util._decorators import ( - Appender, Substitution, cache_readonly, deprecate_kwarg) -from pandas.util._validators import validate_bool_kwarg, validate_fillna_kwargs - +from pandas.core.accessor import PandasDelegate, delegate_names +from pandas.core.algorithms import factorize, take, take_1d, unique1d +from pandas.core.base import NoNewAttributesMixin, PandasObject, _shared_docs +from pandas.core.config import get_option from pandas.core.dtypes.cast import ( coerce_indexer_dtype, maybe_infer_to_datetimelike) from pandas.core.dtypes.common import ( @@ -26,19 +28,13 @@ ABCCategoricalIndex, ABCIndexClass, ABCSeries) from pandas.core.dtypes.inference import is_hashable from pandas.core.dtypes.missing import isna, notna - -from pandas.core.accessor import PandasDelegate, delegate_names -import pandas.core.algorithms as algorithms -from pandas.core.algorithms import factorize, take, take_1d, unique1d -from pandas.core.base import NoNewAttributesMixin, PandasObject, _shared_docs -import pandas.core.common as com -from pandas.core.config import get_option from pandas.core.missing import interpolate_2d from pandas.core.sorting import nargsort - from pandas.io.formats import console from pandas.io.formats.terminal import get_terminal_size - +from pandas.util._decorators import ( + Appender, Substitution, cache_readonly, deprecate_kwarg) +from pandas.util._validators import validate_bool_kwarg, validate_fillna_kwargs from .base import ExtensionArray _take_msg = textwrap.dedent("""\ @@ -1285,7 +1281,9 @@ def shift(self, periods, fill_value=None): elif fill_value in self.categories: fill_value = self.categories.get_loc(fill_value) else: - raise ValueError("'fill_value={}' is not present in this Categorical's categories".format(fill_value)) + raise ValueError("'fill_value={}' is not present " + "in this Categorical's " + "categories".format(fill_value)) if periods > 0: codes[:periods] = fill_value else: From bbfe7f9387a425590702cd4b74bb0b370d6cd021 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 03:34:44 +0200 Subject: [PATCH 028/108] !U fix indents --- pandas/tests/frame/test_timeseries.py | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/pandas/tests/frame/test_timeseries.py b/pandas/tests/frame/test_timeseries.py index 346b56c9a9d69..e16e6bf6cb6d5 100644 --- a/pandas/tests/frame/test_timeseries.py +++ b/pandas/tests/frame/test_timeseries.py @@ -4,25 +4,18 @@ from datetime import datetime, time +import numpy as np import pytest - from numpy.random import randn -import numpy as np -from pandas import (DataFrame, Series, Index, - Timestamp, DatetimeIndex, MultiIndex, - to_datetime, date_range, period_range) import pandas as pd import pandas.tseries.offsets as offsets - -from pandas.util.testing import (assert_series_equal, - assert_frame_equal, - assert_index_equal) - import pandas.util.testing as tm +from pandas import (DataFrame, DatetimeIndex, Index, MultiIndex, Series, Timestamp, date_range, period_range, + to_datetime) from pandas.compat import product - from pandas.tests.frame.common import TestData +from pandas.util.testing import (assert_frame_equal, assert_index_equal, assert_series_equal) @pytest.fixture(params=product([True, False], [True, False])) @@ -324,15 +317,15 @@ def test_shift_fill_value(self): # GH #24128 df = DataFrame([1, 2, 3, 4, 5], index=date_range('1/1/2000', periods=5, freq='H')) - expected = DataFrame([0, 1, 2, 3, 4], - index=date_range('1/1/2000', periods=5, freq='H')) + exp = DataFrame([0, 1, 2, 3, 4], + index=date_range('1/1/2000', periods=5, freq='H')) result = df.shift(1, fill_value=0) - assert_frame_equal(result, expected) + assert_frame_equal(result, exp) - expected = DataFrame([0, 0, 1, 2, 3], - index=date_range('1/1/2000', periods=5, freq='H')) + exp = DataFrame([0, 0, 1, 2, 3], + index=date_range('1/1/2000', periods=5, freq='H')) result = df.shift(2, fill_value=0) - assert_frame_equal(result, expected) + assert_frame_equal(result, exp) def test_shift_empty(self): # Regression test for #8019 From ef55afbe6cc44cfabe03381ad2f6dae8907c103f Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 03:35:17 +0200 Subject: [PATCH 029/108] !U fix indents --- pandas/tests/series/test_timeseries.py | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index f7bd5e7936a30..67a190705fef8 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -6,24 +6,22 @@ import numpy as np import pytest -from pandas._libs.tslib import iNaT -from pandas.compat import StringIO, lrange, product -from pandas.errors import NullFrequencyError -import pandas.util._test_decorators as td - import pandas as pd +import pandas.util._test_decorators as td +import pandas.util.testing as tm from pandas import ( DataFrame, Index, NaT, Series, Timestamp, concat, date_range, offsets, timedelta_range, to_datetime) +from pandas._libs.tslib import iNaT +from pandas.compat import StringIO, lrange, product from pandas.core.indexes.datetimes import DatetimeIndex from pandas.core.indexes.timedeltas import TimedeltaIndex +from pandas.errors import NullFrequencyError from pandas.tests.series.common import TestData -import pandas.util.testing as tm +from pandas.tseries.offsets import BDay, BMonthEnd from pandas.util.testing import ( assert_almost_equal, assert_frame_equal, assert_series_equal) -from pandas.tseries.offsets import BDay, BMonthEnd - def _simple_ts(start, end, freq='D'): rng = date_range(start, end, freq=freq) @@ -140,16 +138,16 @@ def test_shift_fill_value(self): tm.assert_index_equal(result.index, exp_index) tm.assert_numpy_array_equal(result.values, ts.values) - expected = Series([0.0, 1.0, 2.0, 3.0, 4.0], - index=date_range('1/1/2000', periods=5, freq='H')) + exp = Series([0.0, 1.0, 2.0, 3.0, 4.0], + index=date_range('1/1/2000', periods=5, freq='H')) # check that fill value works result = ts.shift(1, fill_value=0.0) - tm.assert_series_equal(result, expected) + tm.assert_series_equal(result, exp) - expected = Series([0.0, 0.0, 1.0, 2.0, 3.0], - index=date_range('1/1/2000', periods=5, freq='H')) + exp = Series([0.0, 0.0, 1.0, 2.0, 3.0], + index=date_range('1/1/2000', periods=5, freq='H')) result = ts.shift(2, fill_value=0.0) - tm.assert_series_equal(result, expected) + tm.assert_series_equal(result, exp) def test_shift_dst(self): # GH 13926 From ce3d3c711d436d5dedba95e3a81ec26a9b994f20 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 14:57:19 +0200 Subject: [PATCH 030/108] !U remove whitespaces --- pandas/core/generic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index c569a75347adf..eb53292be7e96 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8830,8 +8830,8 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, fill_value : object, optional the scalar value to use for newly introduced missing values. the default depends on the dtype of `self`. for numeric data, - ``np.nan`` is used. for datelike, ``pandas.nat`` is used. - + ``np.nan`` is used. for datelike, ``pandas.nat`` is used. + .. versionchanged:: 0.24.0 Returns From e6103a43328aab75c74fe0bbe0e3770c22e567d3 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 14:57:48 +0200 Subject: [PATCH 031/108] !U remove whitespaces --- pandas/core/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index eb53292be7e96..ffdbed7134383 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8868,7 +8868,7 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, 2 NaN 15.0 18.0 3 NaN 30.0 33.0 4 NaN 45.0 48.0 - + >>> df.shift(periods=3, fill_value=0.0) Col1 Col2 Col3 0 0.0 0.0 0.0 From d18b6b74525b9b95cbd90dff4e7fa8fde712fe9a Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 14:58:03 +0200 Subject: [PATCH 032/108] !U fix the line width --- pandas/core/groupby/groupby.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 327ab4a788b6d..197e3a5d004f2 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -2005,7 +2005,8 @@ def shift(self, periods=1, freq=None, axis=0, fill_value=None): """ if freq is not None or axis != 0: - return self.apply(lambda x: x.shift(periods, freq, axis, fill_value)) + return self.apply(lambda x: x.shift(periods, freq, + axis, fill_value)) return self._get_cythonized_result('group_shift_indexer', self.grouper, cython_dtype=np.int64, From 931df66cdcb4743c86cde33e03d20104a3470867 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 14:58:54 +0200 Subject: [PATCH 033/108] !U fix the imports width --- pandas/tests/frame/test_timeseries.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pandas/tests/frame/test_timeseries.py b/pandas/tests/frame/test_timeseries.py index e16e6bf6cb6d5..efcc8250b3352 100644 --- a/pandas/tests/frame/test_timeseries.py +++ b/pandas/tests/frame/test_timeseries.py @@ -11,11 +11,13 @@ import pandas as pd import pandas.tseries.offsets as offsets import pandas.util.testing as tm -from pandas import (DataFrame, DatetimeIndex, Index, MultiIndex, Series, Timestamp, date_range, period_range, +from pandas import (DataFrame, DatetimeIndex, Index, MultiIndex, Series, + Timestamp, date_range, period_range, to_datetime) from pandas.compat import product from pandas.tests.frame.common import TestData -from pandas.util.testing import (assert_frame_equal, assert_index_equal, assert_series_equal) +from pandas.util.testing import (assert_frame_equal, assert_index_equal, + assert_series_equal) @pytest.fixture(params=product([True, False], [True, False])) From 81c01bcaee0e46f065be216078ebcd6b502936e4 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:05:41 +0200 Subject: [PATCH 034/108] !U restore the fill_value --- pandas/core/arrays/base.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index b2ad290314e25..55137873974eb 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -483,6 +483,10 @@ def shift(self, periods=1, fill_value=None): # stored in an instance of your ExtensionArray with `self.dtype`. if not len(self) or periods == 0: return self.copy() + + if fill_value is None: + fill_value = self.dtype.na_value + empty = self._from_sequence( [fill_value] * min(abs(periods), len(self)), dtype=self.dtype From 4ae4d0bbfbd823887a6991a88e3fe83a8392d4ec Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:10:50 +0200 Subject: [PATCH 035/108] !U revert imports --- pandas/core/arrays/categorical.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 902d7c25b059e..149f8e5ac5379 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -5,16 +5,13 @@ import numpy as np -import pandas.compat as compat -import pandas.core.algorithms as algorithms -import pandas.core.common as com from pandas._libs import algos as libalgos, lib +import pandas.compat as compat from pandas.compat import lzip, u from pandas.compat.numpy import function as nv -from pandas.core.accessor import PandasDelegate, delegate_names -from pandas.core.algorithms import factorize, take, take_1d, unique1d -from pandas.core.base import NoNewAttributesMixin, PandasObject, _shared_docs -from pandas.core.config import get_option +from pandas.util._decorators import ( + Appender, Substitution, cache_readonly, deprecate_kwarg) +from pandas.util._validators import validate_bool_kwarg, validate_fillna_kwargs from pandas.core.dtypes.cast import ( coerce_indexer_dtype, maybe_infer_to_datetimelike) from pandas.core.dtypes.common import ( @@ -28,13 +25,17 @@ ABCCategoricalIndex, ABCIndexClass, ABCSeries) from pandas.core.dtypes.inference import is_hashable from pandas.core.dtypes.missing import isna, notna + +from pandas.core.accessor import PandasDelegate, delegate_names +import pandas.core.algorithms as algorithms +from pandas.core.algorithms import factorize, take, take_1d, unique1d +from pandas.core.base import NoNewAttributesMixin, PandasObject, _shared_docs +import pandas.core.common as com +from pandas.core.config import get_option from pandas.core.missing import interpolate_2d from pandas.core.sorting import nargsort from pandas.io.formats import console from pandas.io.formats.terminal import get_terminal_size -from pandas.util._decorators import ( - Appender, Substitution, cache_readonly, deprecate_kwarg) -from pandas.util._validators import validate_bool_kwarg, validate_fillna_kwargs from .base import ExtensionArray _take_msg = textwrap.dedent("""\ From d4d43a388d0f9255cdc032126545abcdb617f5eb Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:13:31 +0200 Subject: [PATCH 036/108] !U revert new lines deletion --- pandas/core/arrays/categorical.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 149f8e5ac5379..3377ce91bae60 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -12,6 +12,7 @@ from pandas.util._decorators import ( Appender, Substitution, cache_readonly, deprecate_kwarg) from pandas.util._validators import validate_bool_kwarg, validate_fillna_kwargs + from pandas.core.dtypes.cast import ( coerce_indexer_dtype, maybe_infer_to_datetimelike) from pandas.core.dtypes.common import ( @@ -34,8 +35,10 @@ from pandas.core.config import get_option from pandas.core.missing import interpolate_2d from pandas.core.sorting import nargsort + from pandas.io.formats import console from pandas.io.formats.terminal import get_terminal_size + from .base import ExtensionArray _take_msg = textwrap.dedent("""\ From 136616191e2c4f9d0ceed5fc5baa3248238d2434 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:16:13 +0200 Subject: [PATCH 037/108] !U revert changes in imports --- pandas/core/generic.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index cb28cde5188c3..46d957d9c6a7a 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -9,41 +9,41 @@ import numpy as np -import pandas as pd -import pandas.compat as compat -import pandas.core.algorithms as algos -import pandas.core.common as com -import pandas.core.indexing as indexing from pandas._libs import Timestamp, iNaT, properties +import pandas.compat as compat from pandas.compat import ( cPickle as pkl, isidentifier, lrange, lzip, map, set_function_name, string_types, to_str, zip) from pandas.compat.numpy import function as nv -from pandas.core import config, missing, nanops -from pandas.core.base import PandasObject, SelectionMixin +from pandas.errors import AbstractMethodError +from pandas.util._decorators import ( + Appender, Substitution, rewrite_axis_style_signature) +from pandas.util._validators import validate_bool_kwarg, validate_fillna_kwargs from pandas.core.dtypes.cast import maybe_promote, maybe_upcast_putmask from pandas.core.dtypes.common import ( ensure_int64, ensure_object, is_bool, is_bool_dtype, - is_datetime64_any_dtype, is_datetime64tz_dtype, is_dict_like, - is_extension_array_dtype, is_integer, is_list_like, is_number, - is_numeric_dtype, is_object_dtype, is_period_arraylike, is_re_compilable, - is_scalar, is_timedelta64_dtype, pandas_dtype) + is_datetime64_any_dtype, is_datetime64tz_dtype, is_dict_like, + is_extension_array_dtype, is_integer, is_list_like, is_number, + is_numeric_dtype, is_object_dtype, is_period_arraylike, is_re_compilable, + is_scalar, is_timedelta64_dtype, pandas_dtype) from pandas.core.dtypes.generic import ABCDataFrame, ABCPanel, ABCSeries from pandas.core.dtypes.inference import is_hashable from pandas.core.dtypes.missing import isna, notna +import pandas as pd +from pandas.core import config, missing, nanops +import pandas.core.algorithms as algos +from pandas.core.base import PandasObject, SelectionMixin +import pandas.core.common as com from pandas.core.index import ( Index, InvalidIndexError, MultiIndex, RangeIndex, ensure_index) from pandas.core.indexes.datetimes import DatetimeIndex from pandas.core.indexes.period import Period, PeriodIndex +import pandas.core.indexing as indexing from pandas.core.internals import BlockManager from pandas.core.ops import _align_method_FRAME -from pandas.errors import AbstractMethodError from pandas.io.formats.format import DataFrameFormatter, format_percentiles from pandas.io.formats.printing import pprint_thing from pandas.tseries.frequencies import to_offset -from pandas.util._decorators import ( - Appender, Substitution, rewrite_axis_style_signature) -from pandas.util._validators import validate_bool_kwarg, validate_fillna_kwargs # goal is to be able to define the docs close to function, while still being # able to share From 2643aa5e792be0d050d7c8ceba05043352b67f2d Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:18:31 +0200 Subject: [PATCH 038/108] !U revert changes in imports --- pandas/core/internals/blocks.py | 35 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index ded799ed8309d..3df90bc70cd01 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1,45 +1,44 @@ # -*- coding: utf-8 -*- +from datetime import date, datetime, timedelta import functools import inspect import re import warnings -from datetime import date, datetime, timedelta -import numpy as np + import numpy as np -import pandas.compat as compat -import pandas.core.algorithms as algos -import pandas.core.common as com -import pandas.core.dtypes.concat as _concat -import pandas.core.missing as missing from pandas._libs import internals as libinternals, lib, tslib, tslibs from pandas._libs.tslibs import Timedelta, conversion +import pandas.compat as compat from pandas.compat import range, zip -from pandas.core.arrays import Categorical, ExtensionArray -from pandas.core.base import PandasObject +from pandas.util._validators import validate_bool_kwarg from pandas.core.dtypes.cast import ( astype_nansafe, find_common_type, infer_dtype_from, infer_dtype_from_scalar, maybe_convert_objects, maybe_downcast_to_dtype, - maybe_infer_dtype_type, maybe_promote, maybe_upcast, soft_convert_objects) + maybe_infer_dtype_type, maybe_promote, maybe_upcast, soft_convert_objects) from pandas.core.dtypes.common import ( - _NS_DTYPE, _TD_DTYPE, ensure_platform_int, is_bool_dtype, is_categorical, - is_categorical_dtype, is_datetime64_dtype, is_datetime64tz_dtype, - is_dtype_equal, is_extension_array_dtype, is_extension_type, - is_float_dtype, is_integer, is_integer_dtype, is_interval_dtype, - is_list_like, is_numeric_v_string_like, is_object_dtype, is_period_dtype, - is_re, is_re_compilable, is_sparse, is_timedelta64_dtype, pandas_dtype) + _NS_DTYPE, _TD_DTYPE, ensure_platform_int, is_bool_dtype, is_categorical, + is_categorical_dtype, is_datetime64_dtype, is_datetime64tz_dtype, + is_dtype_equal, is_extension_array_dtype, is_extension_type, + is_float_dtype, is_integer, is_integer_dtype, is_interval_dtype, + is_list_like, is_numeric_v_string_like, is_object_dtype, is_period_dtype, + is_re, is_re_compilable, is_sparse, is_timedelta64_dtype, pandas_dtype) import pandas.core.dtypes.concat as _concat from pandas.core.dtypes.dtypes import ( - CategoricalDtype, DatetimeTZDtype, ExtensionDtype, PandasExtensionDtype) + CategoricalDtype, DatetimeTZDtype, ExtensionDtype, PandasExtensionDtype) from pandas.core.dtypes.generic import ( ABCDatetimeIndex, ABCExtensionArray, ABCIndexClass, ABCSeries) from pandas.core.dtypes.missing import ( _isna_compat, array_equivalent, is_null_datelike_scalar, isna, notna) +import pandas.core.algorithms as algos +from pandas.core.arrays import Categorical, ExtensionArray +from pandas.core.base import PandasObject +import pandas.core.common as com from pandas.core.indexes.datetimes import DatetimeIndex from pandas.core.indexes.timedeltas import TimedeltaIndex from pandas.core.indexing import check_setitem_lengths +import pandas.core.missing as missing from pandas.io.formats.printing import pprint_thing -from pandas.util._validators import validate_bool_kwarg class Block(PandasObject): From c010413e1fd5c733c55b17863dff3ce51e22e9ab Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:20:23 +0200 Subject: [PATCH 039/108] !U revert changes in imports --- pandas/core/generic.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 46d957d9c6a7a..13e71c566511b 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -19,16 +19,18 @@ from pandas.util._decorators import ( Appender, Substitution, rewrite_axis_style_signature) from pandas.util._validators import validate_bool_kwarg, validate_fillna_kwargs + from pandas.core.dtypes.cast import maybe_promote, maybe_upcast_putmask from pandas.core.dtypes.common import ( ensure_int64, ensure_object, is_bool, is_bool_dtype, - is_datetime64_any_dtype, is_datetime64tz_dtype, is_dict_like, - is_extension_array_dtype, is_integer, is_list_like, is_number, - is_numeric_dtype, is_object_dtype, is_period_arraylike, is_re_compilable, - is_scalar, is_timedelta64_dtype, pandas_dtype) + is_datetime64_any_dtype, is_datetime64tz_dtype, is_dict_like, + is_extension_array_dtype, is_integer, is_list_like, is_number, + is_numeric_dtype, is_object_dtype, is_period_arraylike, is_re_compilable, + is_scalar, is_timedelta64_dtype, pandas_dtype) from pandas.core.dtypes.generic import ABCDataFrame, ABCPanel, ABCSeries from pandas.core.dtypes.inference import is_hashable from pandas.core.dtypes.missing import isna, notna + import pandas as pd from pandas.core import config, missing, nanops import pandas.core.algorithms as algos @@ -41,6 +43,7 @@ import pandas.core.indexing as indexing from pandas.core.internals import BlockManager from pandas.core.ops import _align_method_FRAME + from pandas.io.formats.format import DataFrameFormatter, format_percentiles from pandas.io.formats.printing import pprint_thing from pandas.tseries.frequencies import to_offset From 689bf8edc94cd4cd506f58a599296f43e968b587 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:22:27 +0200 Subject: [PATCH 040/108] !U revert imports --- pandas/core/groupby/groupby.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 105c7b5253c3d..e6d7dc29b2d30 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -8,36 +8,38 @@ class providing the base-class of operations. """ import collections +from contextlib import contextmanager import datetime +from functools import partial, wraps import types import warnings -from contextlib import contextmanager -from functools import partial, wraps import numpy as np -import pandas.compat as compat -import pandas.core.algorithms as algorithms -import pandas.core.common as com from pandas._libs import Timestamp, groupby as libgroupby +import pandas.compat as compat from pandas.compat import callable, range, set_function_name, zip from pandas.compat.numpy import function as nv -from pandas.core.base import ( - DataError, GroupByError, PandasObject, SelectionMixin, SpecificationError) -from pandas.core.config import option_context +from pandas.errors import AbstractMethodError +from pandas.util._decorators import Appender, Substitution, cache_readonly +from pandas.util._validators import validate_kwargs + from pandas.core.dtypes.cast import maybe_downcast_to_dtype from pandas.core.dtypes.common import ( ensure_float, is_extension_array_dtype, is_numeric_dtype, is_scalar) from pandas.core.dtypes.missing import isna, notna + +import pandas.core.algorithms as algorithms +from pandas.core.base import ( + DataError, GroupByError, PandasObject, SelectionMixin, SpecificationError) +import pandas.core.common as com +from pandas.core.config import option_context from pandas.core.frame import DataFrame from pandas.core.generic import NDFrame from pandas.core.groupby import base from pandas.core.index import Index, MultiIndex from pandas.core.series import Series from pandas.core.sorting import get_group_index_sorter -from pandas.errors import AbstractMethodError -from pandas.util._decorators import Appender, Substitution, cache_readonly -from pandas.util._validators import validate_kwargs _doc_template = """ See Also From 463964bdb9a9d3ca0d11238a90a39983b81a3f6d Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:25:34 +0200 Subject: [PATCH 041/108] !U revert imports --- pandas/core/internals/blocks.py | 36 ++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 3df90bc70cd01..14a53413a96cd 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1,44 +1,44 @@ # -*- coding: utf-8 -*- -from datetime import date, datetime, timedelta import functools import inspect import re import warnings +from datetime import date, datetime, timedelta - import numpy as np +import numpy as np +import pandas.compat as compat +import pandas.core.algorithms as algos +import pandas.core.common as com +import pandas.core.dtypes.concat as _concat +import pandas.core.missing as missing from pandas._libs import internals as libinternals, lib, tslib, tslibs from pandas._libs.tslibs import Timedelta, conversion -import pandas.compat as compat from pandas.compat import range, zip -from pandas.util._validators import validate_bool_kwarg +from pandas.core.arrays import Categorical, ExtensionArray +from pandas.core.base import PandasObject from pandas.core.dtypes.cast import ( astype_nansafe, find_common_type, infer_dtype_from, infer_dtype_from_scalar, maybe_convert_objects, maybe_downcast_to_dtype, - maybe_infer_dtype_type, maybe_promote, maybe_upcast, soft_convert_objects) + maybe_infer_dtype_type, maybe_promote, maybe_upcast, soft_convert_objects) from pandas.core.dtypes.common import ( - _NS_DTYPE, _TD_DTYPE, ensure_platform_int, is_bool_dtype, is_categorical, - is_categorical_dtype, is_datetime64_dtype, is_datetime64tz_dtype, - is_dtype_equal, is_extension_array_dtype, is_extension_type, - is_float_dtype, is_integer, is_integer_dtype, is_interval_dtype, - is_list_like, is_numeric_v_string_like, is_object_dtype, is_period_dtype, - is_re, is_re_compilable, is_sparse, is_timedelta64_dtype, pandas_dtype) -import pandas.core.dtypes.concat as _concat + _NS_DTYPE, _TD_DTYPE, ensure_platform_int, is_bool_dtype, is_categorical, + is_categorical_dtype, is_datetime64_dtype, is_datetime64tz_dtype, + is_dtype_equal, is_extension_array_dtype, is_extension_type, + is_float_dtype, is_integer, is_integer_dtype, is_interval_dtype, + is_list_like, is_numeric_v_string_like, is_object_dtype, is_period_dtype, + is_re, is_re_compilable, is_sparse, is_timedelta64_dtype, pandas_dtype) from pandas.core.dtypes.dtypes import ( - CategoricalDtype, DatetimeTZDtype, ExtensionDtype, PandasExtensionDtype) + CategoricalDtype, DatetimeTZDtype, ExtensionDtype, PandasExtensionDtype) from pandas.core.dtypes.generic import ( ABCDatetimeIndex, ABCExtensionArray, ABCIndexClass, ABCSeries) from pandas.core.dtypes.missing import ( _isna_compat, array_equivalent, is_null_datelike_scalar, isna, notna) -import pandas.core.algorithms as algos -from pandas.core.arrays import Categorical, ExtensionArray -from pandas.core.base import PandasObject -import pandas.core.common as com from pandas.core.indexes.datetimes import DatetimeIndex from pandas.core.indexes.timedeltas import TimedeltaIndex from pandas.core.indexing import check_setitem_lengths -import pandas.core.missing as missing from pandas.io.formats.printing import pprint_thing +from pandas.util._validators import validate_bool_kwarg class Block(PandasObject): From b90b00f8ba49de4bc6cc092baaf21155a53afaa5 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:27:38 +0200 Subject: [PATCH 042/108] !U revert imports --- pandas/tests/frame/test_timeseries.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pandas/tests/frame/test_timeseries.py b/pandas/tests/frame/test_timeseries.py index efcc8250b3352..e16e6bf6cb6d5 100644 --- a/pandas/tests/frame/test_timeseries.py +++ b/pandas/tests/frame/test_timeseries.py @@ -11,13 +11,11 @@ import pandas as pd import pandas.tseries.offsets as offsets import pandas.util.testing as tm -from pandas import (DataFrame, DatetimeIndex, Index, MultiIndex, Series, - Timestamp, date_range, period_range, +from pandas import (DataFrame, DatetimeIndex, Index, MultiIndex, Series, Timestamp, date_range, period_range, to_datetime) from pandas.compat import product from pandas.tests.frame.common import TestData -from pandas.util.testing import (assert_frame_equal, assert_index_equal, - assert_series_equal) +from pandas.util.testing import (assert_frame_equal, assert_index_equal, assert_series_equal) @pytest.fixture(params=product([True, False], [True, False])) From 18fab2fe511c7d1d2791bc41100aad3cb785e83a Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:28:57 +0200 Subject: [PATCH 043/108] !U revert imports --- pandas/tests/frame/test_timeseries.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pandas/tests/frame/test_timeseries.py b/pandas/tests/frame/test_timeseries.py index e16e6bf6cb6d5..9bb632a2a3131 100644 --- a/pandas/tests/frame/test_timeseries.py +++ b/pandas/tests/frame/test_timeseries.py @@ -4,18 +4,24 @@ from datetime import datetime, time -import numpy as np import pytest + from numpy.random import randn +import numpy as np + +from pandas import (DataFrame, Series, Index, + Timestamp, DatetimeIndex, MultiIndex, + to_datetime, date_range, period_range) import pandas as pd import pandas.tseries.offsets as offsets + +from pandas.util.testing import (assert_series_equal, + assert_frame_equal, + assert_index_equal) import pandas.util.testing as tm -from pandas import (DataFrame, DatetimeIndex, Index, MultiIndex, Series, Timestamp, date_range, period_range, - to_datetime) from pandas.compat import product from pandas.tests.frame.common import TestData -from pandas.util.testing import (assert_frame_equal, assert_index_equal, assert_series_equal) @pytest.fixture(params=product([True, False], [True, False])) From cb0321552a564537bb718830fa866b3745164214 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:29:30 +0200 Subject: [PATCH 044/108] !U revert imports --- pandas/tests/frame/test_timeseries.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/tests/frame/test_timeseries.py b/pandas/tests/frame/test_timeseries.py index 9bb632a2a3131..dfdda880ab77c 100644 --- a/pandas/tests/frame/test_timeseries.py +++ b/pandas/tests/frame/test_timeseries.py @@ -9,7 +9,6 @@ from numpy.random import randn import numpy as np - from pandas import (DataFrame, Series, Index, Timestamp, DatetimeIndex, MultiIndex, to_datetime, date_range, period_range) From c8242f3d0cf9b333acafc46d9760d8e4089a7bd1 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:29:41 +0200 Subject: [PATCH 045/108] !U revert imports --- pandas/tests/frame/test_timeseries.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pandas/tests/frame/test_timeseries.py b/pandas/tests/frame/test_timeseries.py index dfdda880ab77c..02b83aaf5c131 100644 --- a/pandas/tests/frame/test_timeseries.py +++ b/pandas/tests/frame/test_timeseries.py @@ -18,8 +18,10 @@ from pandas.util.testing import (assert_series_equal, assert_frame_equal, assert_index_equal) + import pandas.util.testing as tm from pandas.compat import product + from pandas.tests.frame.common import TestData From 8e946cc21dcd71ca6ae6dec23e9d6e3b6a865bc7 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:30:00 +0200 Subject: [PATCH 046/108] !U revert imports --- pandas/core/internals/blocks.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 14a53413a96cd..c000644f68929 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1,22 +1,18 @@ # -*- coding: utf-8 -*- +from datetime import date, datetime, timedelta import functools import inspect import re import warnings -from datetime import date, datetime, timedelta import numpy as np -import pandas.compat as compat -import pandas.core.algorithms as algos -import pandas.core.common as com -import pandas.core.dtypes.concat as _concat -import pandas.core.missing as missing from pandas._libs import internals as libinternals, lib, tslib, tslibs from pandas._libs.tslibs import Timedelta, conversion +import pandas.compat as compat from pandas.compat import range, zip -from pandas.core.arrays import Categorical, ExtensionArray -from pandas.core.base import PandasObject +from pandas.util._validators import validate_bool_kwarg + from pandas.core.dtypes.cast import ( astype_nansafe, find_common_type, infer_dtype_from, infer_dtype_from_scalar, maybe_convert_objects, maybe_downcast_to_dtype, @@ -28,17 +24,24 @@ is_float_dtype, is_integer, is_integer_dtype, is_interval_dtype, is_list_like, is_numeric_v_string_like, is_object_dtype, is_period_dtype, is_re, is_re_compilable, is_sparse, is_timedelta64_dtype, pandas_dtype) + +import pandas.core.dtypes.concat as _concat from pandas.core.dtypes.dtypes import ( CategoricalDtype, DatetimeTZDtype, ExtensionDtype, PandasExtensionDtype) from pandas.core.dtypes.generic import ( ABCDatetimeIndex, ABCExtensionArray, ABCIndexClass, ABCSeries) from pandas.core.dtypes.missing import ( _isna_compat, array_equivalent, is_null_datelike_scalar, isna, notna) +import pandas.core.algorithms as algos +from pandas.core.arrays import Categorical, ExtensionArray +from pandas.core.base import PandasObject +import pandas.core.common as com from pandas.core.indexes.datetimes import DatetimeIndex from pandas.core.indexes.timedeltas import TimedeltaIndex from pandas.core.indexing import check_setitem_lengths +import pandas.core.missing as missing + from pandas.io.formats.printing import pprint_thing -from pandas.util._validators import validate_bool_kwarg class Block(PandasObject): From 69e47f303e8813e01f24734e6b59236e5e2eb6db Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:31:53 +0200 Subject: [PATCH 047/108] !U revert imports --- pandas/tests/series/test_timeseries.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index 67a190705fef8..aab378d9399d6 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -6,22 +6,24 @@ import numpy as np import pytest -import pandas as pd +from pandas._libs.tslib import iNaT +from pandas.compat import StringIO, lrange, product +from pandas.errors import NullFrequencyError import pandas.util._test_decorators as td -import pandas.util.testing as tm + +import pandas as pd from pandas import ( DataFrame, Index, NaT, Series, Timestamp, concat, date_range, offsets, timedelta_range, to_datetime) -from pandas._libs.tslib import iNaT -from pandas.compat import StringIO, lrange, product from pandas.core.indexes.datetimes import DatetimeIndex from pandas.core.indexes.timedeltas import TimedeltaIndex -from pandas.errors import NullFrequencyError from pandas.tests.series.common import TestData -from pandas.tseries.offsets import BDay, BMonthEnd +import pandas.util.testing as tm from pandas.util.testing import ( assert_almost_equal, assert_frame_equal, assert_series_equal) +from pandas.tseries.offsets import BDay, BMonthEnd + def _simple_ts(start, end, freq='D'): rng = date_range(start, end, freq=freq) From 8765bee2f2385cd04c0b719e9c0a2e5f8dbac782 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 15:32:56 +0200 Subject: [PATCH 048/108] !U revert imports --- pandas/core/internals/blocks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index c000644f68929..eb9177e455ecb 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -24,7 +24,6 @@ is_float_dtype, is_integer, is_integer_dtype, is_interval_dtype, is_list_like, is_numeric_v_string_like, is_object_dtype, is_period_dtype, is_re, is_re_compilable, is_sparse, is_timedelta64_dtype, pandas_dtype) - import pandas.core.dtypes.concat as _concat from pandas.core.dtypes.dtypes import ( CategoricalDtype, DatetimeTZDtype, ExtensionDtype, PandasExtensionDtype) @@ -32,6 +31,7 @@ ABCDatetimeIndex, ABCExtensionArray, ABCIndexClass, ABCSeries) from pandas.core.dtypes.missing import ( _isna_compat, array_equivalent, is_null_datelike_scalar, isna, notna) + import pandas.core.algorithms as algos from pandas.core.arrays import Categorical, ExtensionArray from pandas.core.base import PandasObject From 9d10a6b073184f3193dc7feec94abda364fa9ed8 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 18:36:52 +0200 Subject: [PATCH 049/108] !U remove doc from the doc --- pandas/core/arrays/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index 55137873974eb..dd9c08053e0ed 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -462,7 +462,7 @@ def shift(self, periods=1, fill_value=None): fill_value : object, optional The scalar value to use for newly introduced missing values. - The default is ``self.dtype.na_value``. + The default is ``self.dtype.na_value`` .. versionadded:: 0.24.0 From 6f4078ab3c7bf24c01c5dda618d7a73a0948a14a Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 21:40:06 +0200 Subject: [PATCH 050/108] !U change description --- pandas/core/arrays/period.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 5a819d11080db..93ccceba20c6c 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -471,7 +471,7 @@ def shift(self, periods=1, fill_value=None): periods : int, default 1 The number of periods to shift. Negative values are allowed for shifting backwards. - fill_value : None or value, default None (NaT) + fill_value : optional, default NaT .. versionadded:: 0.24.0 Returns From 4227dda4a4cfca33e9dee2e5c2fe337f4de54735 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 21:42:04 +0200 Subject: [PATCH 051/108] !U change check for isna instead of is None --- pandas/core/arrays/categorical.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 3377ce91bae60..2c399e6ed6a7e 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -1280,7 +1280,7 @@ def shift(self, periods, fill_value=None): raise NotImplementedError("Categorical with ndim > 1.") if np.prod(codes.shape) and (periods != 0): codes = np.roll(codes, ensure_platform_int(periods), axis=0) - if fill_value is None: + if isna(fill_value): fill_value = -1 elif fill_value in self.categories: fill_value = self.categories.get_loc(fill_value) From ce721ae9174aa22e3a4ad327a9dd17d1da2979c4 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 21:44:31 +0200 Subject: [PATCH 052/108] !U remove the -1 implementation detail --- pandas/core/arrays/categorical.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 2c399e6ed6a7e..abae58f9d77eb 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -1265,7 +1265,6 @@ def shift(self, periods, fill_value=None): Number of periods to move, can be positive or negative fill_value : object, optional The scalar value to use for newly introduced missing values. - The default is ``-1``. .. versionadded:: 0.24.0 From c743004a5e34abaa6d6b6555b8b846152dcde736 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Sun, 9 Dec 2018 21:48:27 +0200 Subject: [PATCH 053/108] !U change doc description + added .. versionadded:: 0.24.0 tag --- pandas/core/groupby/groupby.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index e6d7dc29b2d30..68b4849c96cb1 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -2002,7 +2002,8 @@ def shift(self, periods=1, freq=None, axis=0, fill_value=None): number of periods to shift freq : frequency string axis : axis to shift, default 0 - fill_value : None or value, default None (NaN) + fill_value : optional + .. versionadded:: 0.24.0 """ if freq is not None or axis != 0: From 03e3bd47118501f999e395934155c3334728747d Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 11 Dec 2018 04:39:48 +0200 Subject: [PATCH 054/108] !U add test for sparse array shift with fill_value --- pandas/tests/arrays/sparse/test_array.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index b8cef92f6a6d4..110af9822a46a 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -262,6 +262,12 @@ def test_take_negative(self): exp = SparseArray(np.take(self.arr_data, [-4, -3, -2])) tm.assert_sp_array_equal(self.arr.take([-4, -3, -2]), exp) + def test_shift_fill_value(self): + sparse = SparseArray(np.array([1, 0, 0, 3, 0])) + res = sparse.shift(1, fill_value=0) + exp = SparseArray(np.array([0, 1, 0, 0, 3])) + tm.assert_sp_array_equal(res, exp) + def test_bad_take(self): with pytest.raises(IndexError, match="bounds"): self.arr.take([11]) From e4313da00a89688e6716a89331f018184ca34c37 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 11 Dec 2018 04:53:11 +0200 Subject: [PATCH 055/108] !U add test for gorupby --- pandas/tests/groupby/test_groupby.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index 6d9f60df45ec8..e918b34b54d19 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -1617,6 +1617,23 @@ def test_group_shift_with_null_key(): assert_frame_equal(result, expected) +def test_group_shift_with_fill_value(): + # GH #24128 + n_rows = 1200 + df = DataFrame([(i % 12, i % 3 if i % 3 else np.nan, i) + for i in range(n_rows)], dtype=float, + columns=["A", "B", "Z"], index=None) + g = df.groupby(["A", "B"]) + + expected = DataFrame([0] + [(i + 12 if i % 3 and i < n_rows - 12 + else np.nan) + for i in range(n_rows)], dtype=float, + columns=["Z"], index=None) + result = g.shift(1, fill_value=0.0) + + assert_frame_equal(result, expected) + + def test_pivot_table_values_key_error(): # This test is designed to replicate the error in issue #14938 df = pd.DataFrame({'eventDate': From 85d2b1698aff54f3b8111496c788a2be90727090 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 11 Dec 2018 04:53:26 +0200 Subject: [PATCH 056/108] !U add PR specification to the test --- pandas/tests/arrays/sparse/test_array.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index 110af9822a46a..45dcf55d4bf23 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -263,6 +263,7 @@ def test_take_negative(self): tm.assert_sp_array_equal(self.arr.take([-4, -3, -2]), exp) def test_shift_fill_value(self): + # GH #24128 sparse = SparseArray(np.array([1, 0, 0, 3, 0])) res = sparse.shift(1, fill_value=0) exp = SparseArray(np.array([0, 1, 0, 0, 3])) From da90e89fd8a831e15b146b8c0ad41dbee29fc071 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 11 Dec 2018 23:48:21 +0200 Subject: [PATCH 057/108] !U adjust types --- pandas/tests/arrays/sparse/test_array.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index 45dcf55d4bf23..88624a2a992f3 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -266,7 +266,7 @@ def test_shift_fill_value(self): # GH #24128 sparse = SparseArray(np.array([1, 0, 0, 3, 0])) res = sparse.shift(1, fill_value=0) - exp = SparseArray(np.array([0, 1, 0, 0, 3])) + exp = SparseArray(np.array([0, 1.0, 0, 0, 3.0])) tm.assert_sp_array_equal(res, exp) def test_bad_take(self): From d71be8a07d75b5a3cdaf8719bef76caf32c99f3c Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 11 Dec 2018 23:49:34 +0200 Subject: [PATCH 058/108] !U fix the groupby test --- pandas/tests/groupby/test_groupby.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index e918b34b54d19..8a62d038f5570 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -1627,7 +1627,7 @@ def test_group_shift_with_fill_value(): expected = DataFrame([0] + [(i + 12 if i % 3 and i < n_rows - 12 else np.nan) - for i in range(n_rows)], dtype=float, + for i in range(n_rows-1)], dtype=float, columns=["Z"], index=None) result = g.shift(1, fill_value=0.0) From aca6c9cf65e0ed56d79a518b5c703664e1c9d67c Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 11 Dec 2018 23:54:47 +0200 Subject: [PATCH 059/108] !U add check for fill value in defining the type for result data set --- pandas/core/arrays/sparse.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pandas/core/arrays/sparse.py b/pandas/core/arrays/sparse.py index 8352fee3e32aa..ac8ec1596947e 100644 --- a/pandas/core/arrays/sparse.py +++ b/pandas/core/arrays/sparse.py @@ -892,7 +892,12 @@ def shift(self, periods=1, fill_value=None): if not len(self) or periods == 0: return self.copy() - subtype = np.result_type(np.nan, self.dtype.subtype) + if fill_value is None: + res_type = np.nan + else: + res_type = fill_value + + subtype = np.result_type(res_type, self.dtype.subtype) if subtype != self.dtype.subtype: # just coerce up front From 20361c70ded73468c8357c768f8009c03bfcc4df Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 11 Dec 2018 23:55:18 +0200 Subject: [PATCH 060/108] !U fix the types in the test --- pandas/tests/arrays/sparse/test_array.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index 88624a2a992f3..45dcf55d4bf23 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -266,7 +266,7 @@ def test_shift_fill_value(self): # GH #24128 sparse = SparseArray(np.array([1, 0, 0, 3, 0])) res = sparse.shift(1, fill_value=0) - exp = SparseArray(np.array([0, 1.0, 0, 0, 3.0])) + exp = SparseArray(np.array([0, 1, 0, 0, 3])) tm.assert_sp_array_equal(res, exp) def test_bad_take(self): From 599ccb75d2d88e48472dc313f7a05271b92d85e7 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Wed, 12 Dec 2018 17:47:56 +0200 Subject: [PATCH 061/108] !U fix the test for groupby shift --- pandas/tests/groupby/test_groupby.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index 8a62d038f5570..feafccd63ec29 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -1620,16 +1620,16 @@ def test_group_shift_with_null_key(): def test_group_shift_with_fill_value(): # GH #24128 n_rows = 1200 - df = DataFrame([(i % 12, i % 3 if i % 3 else np.nan, i) + df = DataFrame([(i % 12, i % 3, i) for i in range(n_rows)], dtype=float, columns=["A", "B", "Z"], index=None) g = df.groupby(["A", "B"]) - expected = DataFrame([0] + [(i + 12 if i % 3 and i < n_rows - 12 - else np.nan) - for i in range(n_rows-1)], dtype=float, + expected = DataFrame([(i + 12 if i < n_rows - 12 + else 0) + for i in range(n_rows)], dtype=float, columns=["Z"], index=None) - result = g.shift(1, fill_value=0.0) + result = g.shift(-1, fill_value=0) assert_frame_equal(result, expected) From 1ac273a9623826a7d8b0944117981954c93a68d1 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Wed, 12 Dec 2018 17:59:24 +0200 Subject: [PATCH 062/108] !U update notation of the base shift method --- pandas/core/arrays/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index dd9c08053e0ed..8b1a062fb6736 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -445,7 +445,7 @@ def dropna(self): return self[~self.isna()] def shift(self, periods=1, fill_value=None): - # type: (int) -> ExtensionArray + # type: (int, object) -> ExtensionArray """ Shift values by desired number. From b2074a81c860aa95b982f38af892601fc5e5eb46 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Wed, 12 Dec 2018 17:59:43 +0200 Subject: [PATCH 063/108] !U test categorical shift --- pandas/tests/series/test_timeseries.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index aab378d9399d6..3e38625a94f4e 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -151,6 +151,15 @@ def test_shift_fill_value(self): result = ts.shift(2, fill_value=0.0) tm.assert_series_equal(result, exp) + def test_categorical_shift_fill_value(self): + ts = pd.Series(['a', 'b', 'c', 'd'], dtype="category") + res = ts.shift(1, fill_value='a') + exp = pd.Series(['a', 'a', 'b', 'c'], dtype="category") + tm.assert_series_equal(res, exp) + + with pytest.raises(ValueError): + ts.shift(1, fill_value='f') + def test_shift_dst(self): # GH 13926 dates = date_range('2016-11-06', freq='H', periods=10, tz='US/Eastern') From 0fe2f9591451869d84b75b649196e59c3d304197 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Wed, 12 Dec 2018 19:19:09 +0200 Subject: [PATCH 064/108] !U change the test for categorical --- pandas/tests/series/test_timeseries.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index 3e38625a94f4e..2c3f2d6fd90fb 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -154,8 +154,7 @@ def test_shift_fill_value(self): def test_categorical_shift_fill_value(self): ts = pd.Series(['a', 'b', 'c', 'd'], dtype="category") res = ts.shift(1, fill_value='a') - exp = pd.Series(['a', 'a', 'b', 'c'], dtype="category") - tm.assert_series_equal(res, exp) + tm.assert_equal(np.array(list(res.values)), np.array([ts.values[0]]+list(ts.values[:-1]))) with pytest.raises(ValueError): ts.shift(1, fill_value='f') From 7d33f21a049337f21e0f7be479b9775bacc2e6ec Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Wed, 12 Dec 2018 20:04:17 +0200 Subject: [PATCH 065/108] !U add check for fill value is not None --- pandas/core/groupby/groupby.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 68b4849c96cb1..3a158d394d375 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -2006,7 +2006,7 @@ def shift(self, periods=1, freq=None, axis=0, fill_value=None): .. versionadded:: 0.24.0 """ - if freq is not None or axis != 0: + if freq is not None or axis != 0 or fill_value is not None: return self.apply(lambda x: x.shift(periods, freq, axis, fill_value)) From 578859b32d0b68d91ab954e61e1ae32b3376dda6 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Wed, 12 Dec 2018 20:04:37 +0200 Subject: [PATCH 066/108] !U change n_rows to smaller value --- pandas/tests/groupby/test_groupby.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index feafccd63ec29..8d6fac81bb826 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -1619,7 +1619,7 @@ def test_group_shift_with_null_key(): def test_group_shift_with_fill_value(): # GH #24128 - n_rows = 1200 + n_rows = 24 df = DataFrame([(i % 12, i % 3, i) for i in range(n_rows)], dtype=float, columns=["A", "B", "Z"], index=None) From a016df3ef073c9fde4bbc3d09bf90b308f804fbf Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Wed, 12 Dec 2018 22:46:37 +0200 Subject: [PATCH 067/108] !U select Z column --- pandas/tests/groupby/test_groupby.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index 8d6fac81bb826..d2fac24433ab5 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -1629,7 +1629,7 @@ def test_group_shift_with_fill_value(): else 0) for i in range(n_rows)], dtype=float, columns=["Z"], index=None) - result = g.shift(-1, fill_value=0) + result = g.shift(-1, fill_value=0)["Z"] assert_frame_equal(result, expected) From 39473942e61f7421ae7e19554598de0c451e2d26 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Wed, 12 Dec 2018 22:46:54 +0200 Subject: [PATCH 068/108] !U select as DataFrame --- pandas/tests/groupby/test_groupby.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index d2fac24433ab5..e9de46bba03f1 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -1629,7 +1629,7 @@ def test_group_shift_with_fill_value(): else 0) for i in range(n_rows)], dtype=float, columns=["Z"], index=None) - result = g.shift(-1, fill_value=0)["Z"] + result = g.shift(-1, fill_value=0)[["Z"]] assert_frame_equal(result, expected) From b266a50d1c3c0bc264386d0dcb3d2b3eb3c33a84 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Wed, 12 Dec 2018 23:28:23 +0200 Subject: [PATCH 069/108] !U fix formatting errors --- pandas/tests/series/test_timeseries.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index 2c3f2d6fd90fb..c571524836d8a 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -154,7 +154,8 @@ def test_shift_fill_value(self): def test_categorical_shift_fill_value(self): ts = pd.Series(['a', 'b', 'c', 'd'], dtype="category") res = ts.shift(1, fill_value='a') - tm.assert_equal(np.array(list(res.values)), np.array([ts.values[0]]+list(ts.values[:-1]))) + tm.assert_equal(np.array(list(res.values)), + np.array([ts.values[0]] + list(ts.values[:-1]))) with pytest.raises(ValueError): ts.shift(1, fill_value='f') From fa808a40069c9561de70ba00f633143f018dc7b2 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 13 Dec 2018 02:07:22 +0200 Subject: [PATCH 070/108] !U add specification comment --- pandas/tests/series/test_timeseries.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index c571524836d8a..3274c8b2a7302 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -157,6 +157,7 @@ def test_categorical_shift_fill_value(self): tm.assert_equal(np.array(list(res.values)), np.array([ts.values[0]] + list(ts.values[:-1]))) + # check for incorrect fill_value with pytest.raises(ValueError): ts.shift(1, fill_value='f') From 71b8df18b8142b88f8fc22ce2d088b853e8085f5 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 13 Dec 2018 15:31:14 +0200 Subject: [PATCH 071/108] !U change test for categorical --- pandas/tests/series/test_timeseries.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index 3274c8b2a7302..379c8b1b69b48 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -154,8 +154,10 @@ def test_shift_fill_value(self): def test_categorical_shift_fill_value(self): ts = pd.Series(['a', 'b', 'c', 'd'], dtype="category") res = ts.shift(1, fill_value='a') - tm.assert_equal(np.array(list(res.values)), - np.array([ts.values[0]] + list(ts.values[:-1]))) + expected = pd.Series(pd.Categorical(['a', 'a', 'b', 'c'], + categories=['a', 'b', 'c', 'd'], + ordered=False)) + tm.assert_equal(res, expected) # check for incorrect fill_value with pytest.raises(ValueError): From 31a844ea076c1e391b600dce5e18153ed2647d3b Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 13 Dec 2018 15:35:50 +0200 Subject: [PATCH 072/108] !U add check for different parameters --- pandas/tests/arrays/sparse/test_array.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index 45dcf55d4bf23..6757351e6e5ee 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -264,10 +264,12 @@ def test_take_negative(self): def test_shift_fill_value(self): # GH #24128 - sparse = SparseArray(np.array([1, 0, 0, 3, 0])) - res = sparse.shift(1, fill_value=0) - exp = SparseArray(np.array([0, 1, 0, 0, 3])) - tm.assert_sp_array_equal(res, exp) + fill_values = [0, None, np.nan] + for fill_value in fill_values: + sparse = SparseArray(np.array([1, 0, 0, 3, 0])) + res = sparse.shift(1, fill_value=fill_value) + exp = SparseArray(np.array([fill_value, 1, 0, 0, 3])) + tm.assert_sp_array_equal(res, exp) def test_bad_take(self): with pytest.raises(IndexError, match="bounds"): From 18cbd955782a473ebfa89350e73849a506551116 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 13 Dec 2018 15:37:50 +0200 Subject: [PATCH 073/108] !U move the check to the top --- pandas/core/arrays/sparse.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pandas/core/arrays/sparse.py b/pandas/core/arrays/sparse.py index ac8ec1596947e..8728097e50506 100644 --- a/pandas/core/arrays/sparse.py +++ b/pandas/core/arrays/sparse.py @@ -894,6 +894,7 @@ def shift(self, periods=1, fill_value=None): if fill_value is None: res_type = np.nan + fill_value = self.dtype.na_value else: res_type = fill_value @@ -905,9 +906,6 @@ def shift(self, periods=1, fill_value=None): else: arr = self - if fill_value is None: - fill_value = self.dtype.na_value - empty = self._from_sequence( [fill_value] * min(abs(periods), len(self)), dtype=arr.dtype From d0681505ae06230ca530d4ac20ca53eaf321f844 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Thu, 13 Dec 2018 15:38:52 +0200 Subject: [PATCH 074/108] !U remove index test --- pandas/tests/series/test_timeseries.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index 379c8b1b69b48..1231225f68760 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -134,12 +134,6 @@ def test_shift_fill_value(self): ts = Series([1.0, 2.0, 3.0, 4.0, 5.0], index=date_range('1/1/2000', periods=5, freq='H')) - # fill_value should have no effect on shift with freq - result = ts.shift(1, freq='5T', fill_value=0) - exp_index = ts.index.shift(1, freq='5T') - tm.assert_index_equal(result.index, exp_index) - tm.assert_numpy_array_equal(result.values, ts.values) - exp = Series([0.0, 1.0, 2.0, 3.0, 4.0], index=date_range('1/1/2000', periods=5, freq='H')) # check that fill value works From e665f7d6fc478586b7dd7132f471d962df8f2f6a Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Fri, 14 Dec 2018 02:00:01 +0200 Subject: [PATCH 075/108] !U remove the None from the list --- pandas/tests/arrays/sparse/test_array.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index 6757351e6e5ee..ef3e3fb9e45d9 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -264,7 +264,7 @@ def test_take_negative(self): def test_shift_fill_value(self): # GH #24128 - fill_values = [0, None, np.nan] + fill_values = [0, np.nan] for fill_value in fill_values: sparse = SparseArray(np.array([1, 0, 0, 3, 0])) res = sparse.shift(1, fill_value=fill_value) From c5a95cb39b6e6db8b509ec7710cb5e247351102a Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Fri, 14 Dec 2018 03:14:38 +0200 Subject: [PATCH 076/108] !U change the sparse ArrayTest --- pandas/tests/arrays/sparse/test_array.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index ef3e3fb9e45d9..44eb9f6866e06 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -264,11 +264,16 @@ def test_take_negative(self): def test_shift_fill_value(self): # GH #24128 - fill_values = [0, np.nan] + fill_values = [0, None, np.nan] for fill_value in fill_values: - sparse = SparseArray(np.array([1, 0, 0, 3, 0])) + print(fill_value) + sparse = SparseArray(np.array([1, 0, 0, 3, 0]), + fill_value=8.0) res = sparse.shift(1, fill_value=fill_value) - exp = SparseArray(np.array([fill_value, 1, 0, 0, 3])) + if fill_value is None: + fill_value = res.dtype.na_value + exp = SparseArray(np.array([fill_value, 1, 0, 0, 3]), + fill_value=8.0) tm.assert_sp_array_equal(res, exp) def test_bad_take(self): From b03a3fdaa7eade29c3df32f944fd757353631c6d Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 18 Dec 2018 00:37:22 +0200 Subject: [PATCH 077/108] change the way for parametrizing a test --- pandas/tests/arrays/sparse/test_array.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index 44eb9f6866e06..80f715c6ac86e 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -262,19 +262,19 @@ def test_take_negative(self): exp = SparseArray(np.take(self.arr_data, [-4, -3, -2])) tm.assert_sp_array_equal(self.arr.take([-4, -3, -2]), exp) - def test_shift_fill_value(self): + @pytest.mark.parametrize('fill_value', [ + [0, None, np.nan] + ]) + def test_shift_fill_value(self, fill_value): # GH #24128 - fill_values = [0, None, np.nan] - for fill_value in fill_values: - print(fill_value) - sparse = SparseArray(np.array([1, 0, 0, 3, 0]), - fill_value=8.0) - res = sparse.shift(1, fill_value=fill_value) - if fill_value is None: - fill_value = res.dtype.na_value - exp = SparseArray(np.array([fill_value, 1, 0, 0, 3]), - fill_value=8.0) - tm.assert_sp_array_equal(res, exp) + sparse = SparseArray(np.array([1, 0, 0, 3, 0]), + fill_value=8.0) + res = sparse.shift(1, fill_value=fill_value) + if fill_value is None: + fill_value = res.dtype.na_value + exp = SparseArray(np.array([fill_value, 1, 0, 0, 3]), + fill_value=8.0) + tm.assert_sp_array_equal(res, exp) def test_bad_take(self): with pytest.raises(IndexError, match="bounds"): From d9efb459bcb1be5ab5171ed310f497c3c654b855 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 18 Dec 2018 00:40:04 +0200 Subject: [PATCH 078/108] update the doc --- pandas/core/generic.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 13e71c566511b..789f40c042519 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8840,9 +8840,11 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, axis : {0 or 'index', 1 or 'columns', None}, default None Shift direction. fill_value : object, optional - the scalar value to use for newly introduced missing values. - the default depends on the dtype of `self`. for numeric data, - ``np.nan`` is used. for datelike, ``pandas.nat`` is used. + The scalar value to use for newly introduced missing values. + the default depends on the dtype of `self`. For numeric data, + ``np.nan`` is used. + For datetime, timedelta, or period data, etc. :attr:`NaT` is used. + For extension dtypes, self.dtype.na_value is used. .. versionchanged:: 0.24.0 From 60595c90e828dd90edda226b5baa9732de86fa51 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 18 Dec 2018 00:40:22 +0200 Subject: [PATCH 079/108] update doc --- pandas/core/generic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 789f40c042519..42aba4794cf26 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8841,8 +8841,8 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, Shift direction. fill_value : object, optional The scalar value to use for newly introduced missing values. - the default depends on the dtype of `self`. For numeric data, - ``np.nan`` is used. + the default depends on the dtype of `self`. + For numeric data, ``np.nan`` is used. For datetime, timedelta, or period data, etc. :attr:`NaT` is used. For extension dtypes, self.dtype.na_value is used. From 7fc9900f6a3e12537bc6ab805d9499bed479b3a6 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 18 Dec 2018 00:46:24 +0200 Subject: [PATCH 080/108] add a test for dtype --- pandas/tests/series/test_timeseries.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index 1231225f68760..5bc5a648c404f 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -145,6 +145,10 @@ def test_shift_fill_value(self): result = ts.shift(2, fill_value=0.0) tm.assert_series_equal(result, exp) + ts = pd.Series([1, 2, 3]) + res = ts.shift(2, fill_value=0) + assert res.dtype == ts.dtype + def test_categorical_shift_fill_value(self): ts = pd.Series(['a', 'b', 'c', 'd'], dtype="category") res = ts.shift(1, fill_value='a') From e1a83e2c53c3629bae666ba4a070b5c849fb9429 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 18 Dec 2018 01:25:33 +0200 Subject: [PATCH 081/108] fix the parametrize arguments --- pandas/tests/arrays/sparse/test_array.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index 80f715c6ac86e..122b41ea1fa4c 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -262,9 +262,7 @@ def test_take_negative(self): exp = SparseArray(np.take(self.arr_data, [-4, -3, -2])) tm.assert_sp_array_equal(self.arr.take([-4, -3, -2]), exp) - @pytest.mark.parametrize('fill_value', [ - [0, None, np.nan] - ]) + @pytest.mark.parametrize('fill_value', [0, None, np.nan]) def test_shift_fill_value(self, fill_value): # GH #24128 sparse = SparseArray(np.array([1, 0, 0, 3, 0]), From 7b587c2322238e0eb38cfb3c04dd769719dd432b Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 18 Dec 2018 02:05:25 +0200 Subject: [PATCH 082/108] !U change the doc formatting --- pandas/core/generic.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 42aba4794cf26..58cdbc34d2837 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8841,10 +8841,10 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, Shift direction. fill_value : object, optional The scalar value to use for newly introduced missing values. - the default depends on the dtype of `self`. - For numeric data, ``np.nan`` is used. - For datetime, timedelta, or period data, etc. :attr:`NaT` is used. - For extension dtypes, self.dtype.na_value is used. + the default depends on the dtype of `self`. For numeric data, + ``np.nan`` is used. For datetime, timedelta, or period data, etc. + :attr:`NaT` is used. For extension dtypes, self.dtype.na_value + is used. .. versionchanged:: 0.24.0 From 7bf6768293f3dbac34dee690e81be697dce6a927 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 18 Dec 2018 22:27:03 +0200 Subject: [PATCH 083/108] !U remove the trailing whitespaces --- pandas/core/generic.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 58cdbc34d2837..ff80393fbb6d7 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8841,10 +8841,10 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, Shift direction. fill_value : object, optional The scalar value to use for newly introduced missing values. - the default depends on the dtype of `self`. For numeric data, - ``np.nan`` is used. For datetime, timedelta, or period data, etc. - :attr:`NaT` is used. For extension dtypes, self.dtype.na_value - is used. + the default depends on the dtype of `self`. + For numeric data, ``np.nan`` is used. + For datetime, timedelta, or period data, etc. :attr:`NaT` is used. + For extension dtypes, self.dtype.na_value is used. .. versionchanged:: 0.24.0 From 09f0fdedb6b9bdec8cd8c6c231ea46fd5c9d15dd Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Wed, 19 Dec 2018 00:17:38 +0200 Subject: [PATCH 084/108] Update pandas/core/generic.py Co-Authored-By: ahcub --- pandas/core/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index ff80393fbb6d7..8022456a0e575 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8844,7 +8844,7 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, the default depends on the dtype of `self`. For numeric data, ``np.nan`` is used. For datetime, timedelta, or period data, etc. :attr:`NaT` is used. - For extension dtypes, self.dtype.na_value is used. + For extension dtypes, ``self.dtype.na_value`` is used. .. versionchanged:: 0.24.0 From 6d65cfa633107f3507d1b3186a955a6130583bc0 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Wed, 19 Dec 2018 00:21:14 +0200 Subject: [PATCH 085/108] !U try to remove res_type --- pandas/core/arrays/sparse.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pandas/core/arrays/sparse.py b/pandas/core/arrays/sparse.py index 8728097e50506..6cedf6c1b0ae3 100644 --- a/pandas/core/arrays/sparse.py +++ b/pandas/core/arrays/sparse.py @@ -893,12 +893,9 @@ def shift(self, periods=1, fill_value=None): return self.copy() if fill_value is None: - res_type = np.nan fill_value = self.dtype.na_value - else: - res_type = fill_value - subtype = np.result_type(res_type, self.dtype.subtype) + subtype = np.result_type(fill_value, self.dtype.subtype) if subtype != self.dtype.subtype: # just coerce up front From 3f9b62bbf0bd979328f3e5ba93df301ba9ff8fce Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Wed, 19 Dec 2018 00:34:04 +0200 Subject: [PATCH 086/108] !U add test for categorical shift with fill value as nan --- pandas/tests/groupby/test_categorical.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/pandas/tests/groupby/test_categorical.py b/pandas/tests/groupby/test_categorical.py index f0d0ac246a251..e69b6087b849e 100644 --- a/pandas/tests/groupby/test_categorical.py +++ b/pandas/tests/groupby/test_categorical.py @@ -9,7 +9,8 @@ from pandas.compat import PY37 from pandas import (Index, MultiIndex, CategoricalIndex, DataFrame, Categorical, Series, qcut) -from pandas.util.testing import assert_frame_equal, assert_series_equal +from pandas.util.testing import (assert_equal, + assert_frame_equal, assert_series_equal) import pandas.util.testing as tm @@ -861,3 +862,16 @@ def test_groupby_multiindex_categorical_datetime(): expected = pd.DataFrame( {'values': [0, 4, 8, 3, 4, 5, 6, np.nan, 2]}, index=idx) assert_frame_equal(result, expected) + + +def test_shift(): + ct = pd.Categorical(['a', 'b', 'c', 'd'], + categories=['a', 'b', 'c', 'd'], ordered=False) + expected = pd.Categorical([None, 'a', 'b', 'c'], + categories=['a', 'b', 'c', 'd'], ordered=False) + res = ct.shift(1) + assert_equal(res, expected) + res = ct.shift(1, fill_value=None) + assert_equal(res, expected) + res = ct.shift(1, fill_value=np.nan) + assert_equal(res, expected) From 8fa8a15668d47560e0051e3fe4e9d6a06043f52c Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Wed, 19 Dec 2018 00:34:55 +0200 Subject: [PATCH 087/108] add different variation of nan --- pandas/tests/groupby/test_categorical.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/tests/groupby/test_categorical.py b/pandas/tests/groupby/test_categorical.py index e69b6087b849e..31ed95c640587 100644 --- a/pandas/tests/groupby/test_categorical.py +++ b/pandas/tests/groupby/test_categorical.py @@ -871,7 +871,7 @@ def test_shift(): categories=['a', 'b', 'c', 'd'], ordered=False) res = ct.shift(1) assert_equal(res, expected) - res = ct.shift(1, fill_value=None) - assert_equal(res, expected) res = ct.shift(1, fill_value=np.nan) assert_equal(res, expected) + res = ct.shift(1, fill_value=pd.NaT) + assert_equal(res, expected) From 6c9610839c6e41e534454acb59d8c3959371b4b6 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Thu, 20 Dec 2018 16:22:41 -0600 Subject: [PATCH 088/108] added base test --- pandas/tests/extension/base/methods.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pandas/tests/extension/base/methods.py b/pandas/tests/extension/base/methods.py index 4a409a84f3db4..2bcdb8aa7488c 100644 --- a/pandas/tests/extension/base/methods.py +++ b/pandas/tests/extension/base/methods.py @@ -221,6 +221,17 @@ def test_shift_empty_array(self, data, periods): expected = empty self.assert_extension_array_equal(result, expected) + def test_shift_fill_value(self, data): + arr = data[:4] + fill_value = data[0] + result = arr.shift(1, fill_value=fill_value) + expected = data.take([0, 0, 1, 2]) + self.assert_extension_array_equal(result, expected) + + result = arr.shift(-2, fill_value=fill_value) + expected = data.take([2, 3, 0, 0]) + self.assert_extension_array_equal(result, expected) + @pytest.mark.parametrize("as_frame", [True, False]) def test_hash_pandas_object_works(self, data, as_frame): # https://github.com/pandas-dev/pandas/issues/23066 From eb48cfe3ff6038f6ce35e0600f972721337bded2 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 20:02:33 +0200 Subject: [PATCH 089/108] change the fill_value so the result data set stays int --- pandas/core/generic.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 8022456a0e575..949af2f874fdf 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8883,13 +8883,13 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, 3 NaN 30.0 33.0 4 NaN 45.0 48.0 - >>> df.shift(periods=3, fill_value=0.0) + >>> df.shift(periods=3, fill_value=0) Col1 Col2 Col3 - 0 0.0 0.0 0.0 - 1 0.0 0.0 0.0 - 2 0.0 0.0 0.0 - 3 10.0 13.0 17.0 - 4 20.0 23.0 27.0 + 0 0 0 0 + 1 0 0 0 + 2 0 0 0 + 3 10 13 17 + 4 20 23 27 """) @Appender(_shared_docs['shift'] % _shared_doc_kwargs) From a72cffe30e2903b04cbc8d0285c959fb7698fa2e Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 20:03:29 +0200 Subject: [PATCH 090/108] add a blank line before the version tag --- pandas/core/arrays/period.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 93ccceba20c6c..a90b9377ff66e 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -472,6 +472,7 @@ def shift(self, periods=1, fill_value=None): The number of periods to shift. Negative values are allowed for shifting backwards. fill_value : optional, default NaT + .. versionadded:: 0.24.0 Returns From 25b466116212b6c259d4b009cd05103b00398c14 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 20:03:59 +0200 Subject: [PATCH 091/108] add a blank line before the version tag --- pandas/core/groupby/groupby.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 3a158d394d375..5658d7a541e27 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -2003,6 +2003,7 @@ def shift(self, periods=1, freq=None, axis=0, fill_value=None): freq : frequency string axis : axis to shift, default 0 fill_value : optional + .. versionadded:: 0.24.0 """ From 0afad10d0ecfab82e28d8a397720a64e2bd8c888 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 20:05:31 +0200 Subject: [PATCH 092/108] change the fill_value check for na --- pandas/core/internals/blocks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index be075b19fef5f..0ccfab93c2830 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -3040,7 +3040,7 @@ def shift(self, periods, axis=0, fill_value=None): new_values = self.values.asi8.take(indexer) - if fill_value is None: + if isna(fill_value): fill_value = tslibs.iNaT if periods > 0: new_values[:periods] = fill_value From bb679059366160e1721da2d4c6295a3bcec22b4b Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 20:10:49 +0200 Subject: [PATCH 093/108] parametrize on fill value with decorator instead of the test internals --- pandas/tests/groupby/test_categorical.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/pandas/tests/groupby/test_categorical.py b/pandas/tests/groupby/test_categorical.py index 26ef442ed10ad..7eda113be0e36 100644 --- a/pandas/tests/groupby/test_categorical.py +++ b/pandas/tests/groupby/test_categorical.py @@ -863,14 +863,11 @@ def test_groupby_multiindex_categorical_datetime(): assert_frame_equal(result, expected) -def test_shift(): +@pytest.mark.parametrize('fill_value', [None, np.nan, pd.NaT]) +def test_shift(fill_value): ct = pd.Categorical(['a', 'b', 'c', 'd'], categories=['a', 'b', 'c', 'd'], ordered=False) expected = pd.Categorical([None, 'a', 'b', 'c'], categories=['a', 'b', 'c', 'd'], ordered=False) - res = ct.shift(1) - assert_equal(res, expected) - res = ct.shift(1, fill_value=np.nan) - assert_equal(res, expected) - res = ct.shift(1, fill_value=pd.NaT) + res = ct.shift(1, fill_value=fill_value) assert_equal(res, expected) From f5aad59ef0149b2f3e26489c86275397cf6319d7 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 20:12:50 +0200 Subject: [PATCH 094/108] change check for is None to isna --- pandas/core/arrays/base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index b4e413f16247e..eab3cfc86e7a8 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -9,6 +9,7 @@ import numpy as np +from pandas.core.dtypes.missing import isna from pandas.compat import PY3, set_function_name from pandas.compat.numpy import function as nv from pandas.errors import AbstractMethodError @@ -486,7 +487,7 @@ def shift(self, periods=1, fill_value=None): if not len(self) or periods == 0: return self.copy() - if fill_value is None: + if isna(fill_value): fill_value = self.dtype.na_value empty = self._from_sequence( From 025f0db8a5a073bf571082bdc6dfa3e984115bab Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 20:14:20 +0200 Subject: [PATCH 095/108] change check for is None to isna --- pandas/tests/arrays/sparse/test_array.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index 81876e73c80cc..3ccffa3cf7902 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -5,6 +5,7 @@ import numpy as np import pytest +from pandas.core.dtypes.missing import isna from pandas._libs.sparse import IntIndex from pandas.compat import range import pandas.util._test_decorators as td @@ -268,7 +269,7 @@ def test_shift_fill_value(self, fill_value): sparse = SparseArray(np.array([1, 0, 0, 3, 0]), fill_value=8.0) res = sparse.shift(1, fill_value=fill_value) - if fill_value is None: + if isna(fill_value): fill_value = res.dtype.na_value exp = SparseArray(np.array([fill_value, 1, 0, 0, 3]), fill_value=8.0) From 8ce460af74da21b1832ce448fc5860d015cea718 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 20:14:26 +0200 Subject: [PATCH 096/108] change check for is None to isna --- pandas/core/arrays/sparse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/arrays/sparse.py b/pandas/core/arrays/sparse.py index 15b809f8fd92a..e4a8c21bbb839 100644 --- a/pandas/core/arrays/sparse.py +++ b/pandas/core/arrays/sparse.py @@ -894,7 +894,7 @@ def shift(self, periods=1, fill_value=None): if not len(self) or periods == 0: return self.copy() - if fill_value is None: + if isna(fill_value): fill_value = self.dtype.na_value subtype = np.result_type(fill_value, self.dtype.subtype) From dce5aa1799e0080d85e4265490a315831ec4f70a Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 20:15:20 +0200 Subject: [PATCH 097/108] change check for is None to isna --- pandas/core/groupby/groupby.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index fc01c8a1bd313..60b6c843492c7 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -2009,7 +2009,7 @@ def shift(self, periods=1, freq=None, axis=0, fill_value=None): .. versionadded:: 0.24.0 """ - if freq is not None or axis != 0 or fill_value is not None: + if freq is not None or axis != 0 or not isna(fill_value): return self.apply(lambda x: x.shift(periods, freq, axis, fill_value)) From d60632addbb2906cf4895ae255ea51f2f21276f8 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 22:05:11 +0200 Subject: [PATCH 098/108] fix imports sorting --- pandas/tests/arrays/sparse/test_array.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index 3ccffa3cf7902..9340f35eaa019 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -5,13 +5,13 @@ import numpy as np import pytest -from pandas.core.dtypes.missing import isna from pandas._libs.sparse import IntIndex from pandas.compat import range import pandas.util._test_decorators as td import pandas as pd from pandas.core.sparse.api import SparseArray, SparseDtype, SparseSeries +from pandas.core.dtypes.missing import isna import pandas.util.testing as tm from pandas.util.testing import assert_almost_equal From a0ab35dab62006a0dc6b8b7aa009107691a908c6 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 22:05:23 +0200 Subject: [PATCH 099/108] fix imports sorting --- pandas/core/arrays/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index eab3cfc86e7a8..06303e6bb0498 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -9,12 +9,12 @@ import numpy as np -from pandas.core.dtypes.missing import isna from pandas.compat import PY3, set_function_name from pandas.compat.numpy import function as nv from pandas.errors import AbstractMethodError from pandas.core.dtypes.common import is_list_like +from pandas.core.dtypes.missing import isna from pandas.core.dtypes.generic import ABCIndexClass, ABCSeries from pandas.core import ops From fd23842a0e8b07a05ecc3525931a7019487a9a8c Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 22:20:08 +0200 Subject: [PATCH 100/108] fix imports sorting --- pandas/core/arrays/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index 06303e6bb0498..262f043e1f0a1 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -14,8 +14,8 @@ from pandas.errors import AbstractMethodError from pandas.core.dtypes.common import is_list_like -from pandas.core.dtypes.missing import isna from pandas.core.dtypes.generic import ABCIndexClass, ABCSeries +from pandas.core.dtypes.missing import isna from pandas.core import ops From 3503e86f4baeaf5134e6474e6d62818bc9f04fad Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 22:20:51 +0200 Subject: [PATCH 101/108] fix imports sorting --- pandas/tests/arrays/sparse/test_array.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index 9340f35eaa019..5d7f9ec69a573 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -9,9 +9,10 @@ from pandas.compat import range import pandas.util._test_decorators as td +from pandas.core.dtypes.missing import isna + import pandas as pd from pandas.core.sparse.api import SparseArray, SparseDtype, SparseSeries -from pandas.core.dtypes.missing import isna import pandas.util.testing as tm from pandas.util.testing import assert_almost_equal From 674f15db95f4bc5fd63a00e4746c97fc2de5839b Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 23:18:19 +0200 Subject: [PATCH 102/108] Add the whatsnew entry --- doc/source/whatsnew/v0.24.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index 1fb43de5f4c5a..613f9eeb6e8e4 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -31,6 +31,7 @@ New features - :func:`read_feather` now accepts ``columns`` as an argument, allowing the user to specify which columns should be read. (:issue:`24025`) - :func:`DataFrame.to_html` now accepts ``render_links`` as an argument, allowing the user to generate HTML with links to any URLs that appear in the DataFrame. See the :ref:`section on writing HTML ` in the IO docs for example usage. (:issue:`2679`) +- :func:`shift` method for DataFrame, Series, ExtensionArray, SparseArray, Period, GroupBy, NDFrame, Block now accepts fill_value as an argument, allowing the user to specify a value which will be used instead of NA/NaT in the empty periods .. _whatsnew_0240.values_api: From 3c896ab110dc78d2156924ea1b2f607e94395fd5 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 23:21:47 +0200 Subject: [PATCH 103/108] change func to meth --- doc/source/whatsnew/v0.24.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index 613f9eeb6e8e4..904814c956c89 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -31,7 +31,7 @@ New features - :func:`read_feather` now accepts ``columns`` as an argument, allowing the user to specify which columns should be read. (:issue:`24025`) - :func:`DataFrame.to_html` now accepts ``render_links`` as an argument, allowing the user to generate HTML with links to any URLs that appear in the DataFrame. See the :ref:`section on writing HTML ` in the IO docs for example usage. (:issue:`2679`) -- :func:`shift` method for DataFrame, Series, ExtensionArray, SparseArray, Period, GroupBy, NDFrame, Block now accepts fill_value as an argument, allowing the user to specify a value which will be used instead of NA/NaT in the empty periods +- :meth:`shift` method for DataFrame, Series, ExtensionArray, SparseArray, Period, GroupBy, NDFrame, Block now accepts fill_value as an argument, allowing the user to specify a value which will be used instead of NA/NaT in the empty periods .. _whatsnew_0240.values_api: From b9d335aedb435babcbea27e0318c9528786f4163 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 23:24:02 +0200 Subject: [PATCH 104/108] change the description in whatsnew --- doc/source/whatsnew/v0.24.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index 904814c956c89..72879f495ca76 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -31,7 +31,7 @@ New features - :func:`read_feather` now accepts ``columns`` as an argument, allowing the user to specify which columns should be read. (:issue:`24025`) - :func:`DataFrame.to_html` now accepts ``render_links`` as an argument, allowing the user to generate HTML with links to any URLs that appear in the DataFrame. See the :ref:`section on writing HTML ` in the IO docs for example usage. (:issue:`2679`) -- :meth:`shift` method for DataFrame, Series, ExtensionArray, SparseArray, Period, GroupBy, NDFrame, Block now accepts fill_value as an argument, allowing the user to specify a value which will be used instead of NA/NaT in the empty periods +- :meth:`DataFrame.shift` :meth:`Series.shift`, :meth:`ExtensionArray.shift`, :meth:`SparseArray.shift`, :meth:`Period.shift`, :meth:`GroupBy.shift`, :meth:`NDFrame.shift` and :meth:`Block.shift` now accepts fill_value as an argument, allowing the user to specify a value which will be used instead of NA/NaT in the empty periods .. _whatsnew_0240.values_api: From 4fcca01ef6b1085712e4c08092de61274d9e67d3 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 23:24:21 +0200 Subject: [PATCH 105/108] fix typo --- doc/source/whatsnew/v0.24.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index 72879f495ca76..e13b9736a9361 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -31,7 +31,7 @@ New features - :func:`read_feather` now accepts ``columns`` as an argument, allowing the user to specify which columns should be read. (:issue:`24025`) - :func:`DataFrame.to_html` now accepts ``render_links`` as an argument, allowing the user to generate HTML with links to any URLs that appear in the DataFrame. See the :ref:`section on writing HTML ` in the IO docs for example usage. (:issue:`2679`) -- :meth:`DataFrame.shift` :meth:`Series.shift`, :meth:`ExtensionArray.shift`, :meth:`SparseArray.shift`, :meth:`Period.shift`, :meth:`GroupBy.shift`, :meth:`NDFrame.shift` and :meth:`Block.shift` now accepts fill_value as an argument, allowing the user to specify a value which will be used instead of NA/NaT in the empty periods +- :meth:`DataFrame.shift` :meth:`Series.shift`, :meth:`ExtensionArray.shift`, :meth:`SparseArray.shift`, :meth:`Period.shift`, :meth:`GroupBy.shift`, :meth:`NDFrame.shift` and :meth:`Block.shift` now accept fill_value as an argument, allowing the user to specify a value which will be used instead of NA/NaT in the empty periods .. _whatsnew_0240.values_api: From a24f5c825e0c378330adf332085ab361e1b6aab2 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Tue, 25 Dec 2018 23:25:00 +0200 Subject: [PATCH 106/108] Add categorical to the description --- doc/source/whatsnew/v0.24.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index e13b9736a9361..549dd36d4fbeb 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -31,7 +31,7 @@ New features - :func:`read_feather` now accepts ``columns`` as an argument, allowing the user to specify which columns should be read. (:issue:`24025`) - :func:`DataFrame.to_html` now accepts ``render_links`` as an argument, allowing the user to generate HTML with links to any URLs that appear in the DataFrame. See the :ref:`section on writing HTML ` in the IO docs for example usage. (:issue:`2679`) -- :meth:`DataFrame.shift` :meth:`Series.shift`, :meth:`ExtensionArray.shift`, :meth:`SparseArray.shift`, :meth:`Period.shift`, :meth:`GroupBy.shift`, :meth:`NDFrame.shift` and :meth:`Block.shift` now accept fill_value as an argument, allowing the user to specify a value which will be used instead of NA/NaT in the empty periods +- :meth:`DataFrame.shift` :meth:`Series.shift`, :meth:`ExtensionArray.shift`, :meth:`SparseArray.shift`, :meth:`Period.shift`, :meth:`GroupBy.shift`, :meth:`Categorical.shift`, :meth:`NDFrame.shift` and :meth:`Block.shift` now accept fill_value as an argument, allowing the user to specify a value which will be used instead of NA/NaT in the empty periods .. _whatsnew_0240.values_api: From a92ddfbd0461c0229662a77b98689a5c58a6b600 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Wed, 26 Dec 2018 02:14:43 +0200 Subject: [PATCH 107/108] change import of isna in test --- pandas/tests/arrays/sparse/test_array.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index 5d7f9ec69a573..9c13a20726553 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -9,9 +9,8 @@ from pandas.compat import range import pandas.util._test_decorators as td -from pandas.core.dtypes.missing import isna - import pandas as pd +from pandas import isna from pandas.core.sparse.api import SparseArray, SparseDtype, SparseSeries import pandas.util.testing as tm from pandas.util.testing import assert_almost_equal From a03cbf5e4afe65c8b6fe8a1eb1eee517d0fc5913 Mon Sep 17 00:00:00 2001 From: Alexander Buchkovsky Date: Wed, 26 Dec 2018 02:16:42 +0200 Subject: [PATCH 108/108] add backticks for fill_value and add the issue number --- doc/source/whatsnew/v0.24.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index 549dd36d4fbeb..2693c98e56582 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -31,7 +31,7 @@ New features - :func:`read_feather` now accepts ``columns`` as an argument, allowing the user to specify which columns should be read. (:issue:`24025`) - :func:`DataFrame.to_html` now accepts ``render_links`` as an argument, allowing the user to generate HTML with links to any URLs that appear in the DataFrame. See the :ref:`section on writing HTML ` in the IO docs for example usage. (:issue:`2679`) -- :meth:`DataFrame.shift` :meth:`Series.shift`, :meth:`ExtensionArray.shift`, :meth:`SparseArray.shift`, :meth:`Period.shift`, :meth:`GroupBy.shift`, :meth:`Categorical.shift`, :meth:`NDFrame.shift` and :meth:`Block.shift` now accept fill_value as an argument, allowing the user to specify a value which will be used instead of NA/NaT in the empty periods +- :meth:`DataFrame.shift` :meth:`Series.shift`, :meth:`ExtensionArray.shift`, :meth:`SparseArray.shift`, :meth:`Period.shift`, :meth:`GroupBy.shift`, :meth:`Categorical.shift`, :meth:`NDFrame.shift` and :meth:`Block.shift` now accept `fill_value` as an argument, allowing the user to specify a value which will be used instead of NA/NaT in the empty periods. (:issue:`15486`) .. _whatsnew_0240.values_api: