Skip to content

Commit 9ab2d4d

Browse files
committed
ENH: fill_value argument for shift
1 parent c3e550c commit 9ab2d4d

File tree

6 files changed

+44
-13
lines changed

6 files changed

+44
-13
lines changed

pandas/core/arrays/datetimelike.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ def _addsub_offset_array(self, other, op):
780780
return self._from_sequence(res_values)
781781

782782
@deprecate_kwarg(old_arg_name='n', new_arg_name='periods')
783-
def shift(self, periods, freq=None):
783+
def shift(self, periods, freq=None, fill_value=np.nan):
784784
"""
785785
Shift index by desired number of time frequency increments.
786786
@@ -810,9 +810,9 @@ def shift(self, periods, freq=None):
810810
Index.shift : Shift values of Index.
811811
PeriodIndex.shift : Shift values of PeriodIndex.
812812
"""
813-
return self._time_shift(periods=periods, freq=freq)
813+
return self._time_shift(periods=periods, freq=freq, fill_value=np.nan)
814814

815-
def _time_shift(self, periods, freq=None):
815+
def _time_shift(self, periods, freq=None, fill_value=np.nan):
816816
"""
817817
Shift each value by `periods`.
818818

pandas/core/frame.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3867,9 +3867,9 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None,
38673867
method=method)
38683868

38693869
@Appender(_shared_docs['shift'] % _shared_doc_kwargs)
3870-
def shift(self, periods=1, freq=None, axis=0):
3870+
def shift(self, periods=1, freq=None, axis=0, fill_value=np.nan):
38713871
return super(DataFrame, self).shift(periods=periods, freq=freq,
3872-
axis=axis)
3872+
axis=axis, fill_value=fill_value)
38733873

38743874
def set_index(self, keys, drop=True, append=False, inplace=False,
38753875
verify_integrity=False):

pandas/core/generic.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8868,15 +8868,15 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None,
88688868
""")
88698869

88708870
@Appender(_shared_docs['shift'] % _shared_doc_kwargs)
8871-
def shift(self, periods=1, freq=None, axis=0):
8871+
def shift(self, periods=1, freq=None, axis=0, fill_value=np.nan):
88728872
if periods == 0:
88738873
return self.copy()
88748874

88758875
block_axis = self._get_block_manager_axis(axis)
88768876
if freq is None:
8877-
new_data = self._data.shift(periods=periods, axis=block_axis)
8877+
new_data = self._data.shift(periods=periods, axis=block_axis, fill_value=fill_value)
88788878
else:
8879-
return self.tshift(periods, freq)
8879+
return self.tshift(periods, freq, fill_value=fill_value)
88808880

88818881
return self._constructor(new_data).__finalize__(self)
88828882

@@ -8916,7 +8916,7 @@ def slice_shift(self, periods=1, axis=0):
89168916

89178917
return new_obj.__finalize__(self)
89188918

8919-
def tshift(self, periods=1, freq=None, axis=0):
8919+
def tshift(self, periods=1, freq=None, axis=0, fill_value=np.nan):
89208920
"""
89218921
Shift the time index, using the index's frequency if available.
89228922

pandas/core/internals/blocks.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,12 +1260,12 @@ def diff(self, n, axis=1):
12601260
new_values = algos.diff(self.values, n, axis=axis)
12611261
return [self.make_block(values=new_values)]
12621262

1263-
def shift(self, periods, axis=0):
1263+
def shift(self, periods, axis=0, fill_value=np.nan):
12641264
""" shift the block by periods, possibly upcast """
12651265

12661266
# convert integer to float if necessary. need to do a lot more than
12671267
# that, handle boolean etc also
1268-
new_values, fill_value = maybe_upcast(self.values)
1268+
new_values, fill_value = maybe_upcast(self.values, fill_value)
12691269

12701270
# make sure array sent to np.roll is c_contiguous
12711271
f_ordered = new_values.flags.f_contiguous

pandas/core/series.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3714,8 +3714,8 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None,
37143714
regex=regex, method=method)
37153715

37163716
@Appender(generic._shared_docs['shift'] % _shared_doc_kwargs)
3717-
def shift(self, periods=1, freq=None, axis=0):
3718-
return super(Series, self).shift(periods=periods, freq=freq, axis=axis)
3717+
def shift(self, periods=1, freq=None, axis=0, fill_value=np.nan):
3718+
return super(Series, self).shift(periods=periods, freq=freq, axis=axis, fill_value=fill_value)
37193719

37203720
def reindex_axis(self, labels, axis=0, **kwargs):
37213721
"""

pandas/tests/series/test_timeseries.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,37 @@ def test_shift2(self):
129129
idx = DatetimeIndex(['2000-01-01', '2000-01-02', '2000-01-04'])
130130
pytest.raises(NullFrequencyError, idx.shift, 1)
131131

132+
def test_shift_fill_value(self):
133+
ts = Series(np.random.randn(5),
134+
index=date_range('1/1/2000', periods=5, freq='H'))
135+
136+
# fill_value should have no effect on shift with freq
137+
result = ts.shift(1, freq='5T', fill_value=0)
138+
exp_index = ts.index.shift(1, freq='5T')
139+
tm.assert_index_equal(result.index, exp_index)
140+
tm.assert_equal(result.iloc[0].value, ts.iloc[0].value)
141+
142+
# check that fill value works
143+
result = ts.shift(1, fill_value=0.0)
144+
tm.assert_equal(result.iloc[0].value, 0.0)
145+
tm.assert_equal(result.iloc[1].value, ts.iloc[0].value)
146+
147+
result = ts.shift(2, fill_value=0.0)
148+
tm.assert_equal(result.iloc[0].value, 0.0)
149+
tm.assert_equal(result.iloc[1].value, 0.0)
150+
tm.assert_equal(result.iloc[2].value, ts.iloc[0].value)
151+
152+
df = DataFrame(np.random.randn(5), index=date_range('1/1/2000', periods=5, freq='H'))
153+
154+
result = df.shift(1, fill_value=0.0)
155+
tm.assert_equal(result.iloc[0, 0].value, 0.0)
156+
tm.assert_equal(result.iloc[1, 0].value, df.iloc[0, 0].value)
157+
158+
result = df.shift(2, fill_value=0.0)
159+
tm.assert_equal(result.iloc[0, 0].value, 0.0)
160+
tm.assert_equal(result.iloc[1, 0].value, 0.0)
161+
tm.assert_equal(result.iloc[2, 0].value, df.iloc[0, 0].value)
162+
132163
def test_shift_dst(self):
133164
# GH 13926
134165
dates = date_range('2016-11-06', freq='H', periods=10, tz='US/Eastern')

0 commit comments

Comments
 (0)