diff --git a/doc/source/api.rst b/doc/source/api.rst index 4e02f7b11f466..6b3e6bedcb24b 100644 --- a/doc/source/api.rst +++ b/doc/source/api.rst @@ -2025,6 +2025,7 @@ Upsampling Resampler.backfill Resampler.bfill Resampler.pad + Resampler.nearest Resampler.fillna Resampler.asfreq Resampler.interpolate diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt index 722e19d2703b5..86bd3c354ccc6 100644 --- a/doc/source/whatsnew/v0.21.0.txt +++ b/doc/source/whatsnew/v0.21.0.txt @@ -28,6 +28,7 @@ New features and :class:`~pandas.ExcelWriter` to work properly with the file system path protocol (:issue:`13823`) - Added ``skipna`` parameter to :func:`~pandas.api.types.infer_dtype` to support type inference in the presence of missing values (:issue:`17059`). +- :class:`~pandas.Resampler.nearest` is added to support nearest-neighbor upsampling (:issue:`17496`). .. _whatsnew_0210.enhancements.infer_objects: diff --git a/pandas/core/resample.py b/pandas/core/resample.py index 96e7a6a3b3904..01c7e875b8ecc 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -455,6 +455,10 @@ def pad(self, limit=None): limit : integer, optional limit of how many values to fill + Returns + ------- + an upsampled Series + See Also -------- Series.fillna @@ -463,6 +467,28 @@ def pad(self, limit=None): return self._upsample('pad', limit=limit) ffill = pad + def nearest(self, limit=None): + """ + Fill values with nearest neighbor starting from center + + Parameters + ---------- + limit : integer, optional + limit of how many values to fill + + .. versionadded:: 0.21.0 + + Returns + ------- + an upsampled Series + + See Also + -------- + Series.fillna + DataFrame.fillna + """ + return self._upsample('nearest', limit=limit) + def backfill(self, limit=None): """ Backward fill the values @@ -472,6 +498,10 @@ def backfill(self, limit=None): limit : integer, optional limit of how many values to fill + Returns + ------- + an upsampled Series + See Also -------- Series.fillna diff --git a/pandas/tests/test_resample.py b/pandas/tests/test_resample.py index d42e37048d87f..28a68a0a6e36d 100644 --- a/pandas/tests/test_resample.py +++ b/pandas/tests/test_resample.py @@ -1329,6 +1329,14 @@ def test_upsample_with_limit(self): expected = ts.reindex(result.index, method='ffill', limit=2) assert_series_equal(result, expected) + def test_nearest_upsample_with_limit(self): + rng = date_range('1/1/2000', periods=3, freq='5t') + ts = Series(np.random.randn(len(rng)), rng) + + result = ts.resample('t').nearest(limit=2) + expected = ts.reindex(result.index, method='nearest', limit=2) + assert_series_equal(result, expected) + def test_resample_ohlc(self): s = self.series @@ -2934,6 +2942,24 @@ def test_getitem_multiple(self): result = r['buyer'].count() assert_series_equal(result, expected) + def test_nearest(self): + + # GH 17496 + # Resample nearest + index = pd.date_range('1/1/2000', periods=3, freq='T') + result = pd.Series(range(3), index=index).resample('20s').nearest() + + expected = pd.Series( + np.array([0, 0, 1, 1, 1, 2, 2]), + index=pd.DatetimeIndex( + ['2000-01-01 00:00:00', '2000-01-01 00:00:20', + '2000-01-01 00:00:40', '2000-01-01 00:01:00', + '2000-01-01 00:01:20', '2000-01-01 00:01:40', + '2000-01-01 00:02:00'], + dtype='datetime64[ns]', + freq='20S')) + assert_series_equal(result, expected) + def test_methods(self): g = self.frame.groupby('A') r = g.resample('2s') @@ -2960,7 +2986,7 @@ def test_methods(self): expected = g.B.apply(lambda x: getattr(x.resample('2s'), f)()) assert_series_equal(result, expected) - for f in ['backfill', 'ffill', 'asfreq']: + for f in ['nearest', 'backfill', 'ffill', 'asfreq']: result = getattr(r, f)() expected = g.apply(lambda x: getattr(x.resample('2s'), f)()) assert_frame_equal(result, expected)