diff --git a/doc/source/whatsnew/v0.17.0.txt b/doc/source/whatsnew/v0.17.0.txt index 690dd1ab196b0..9f9813cefd305 100644 --- a/doc/source/whatsnew/v0.17.0.txt +++ b/doc/source/whatsnew/v0.17.0.txt @@ -44,6 +44,7 @@ Other API Changes ^^^^^^^^^^^^^^^^^ - Enable writing Excel files in :ref:`memory <_io.excel_writing_buffer>` using StringIO/BytesIO (:issue:`7074`) - Enable serialization of lists and dicts to strings in ExcelWriter (:issue:`8188`) +- Allow passing `kwargs` to the interpolation methods (:issue:`10378`). .. _whatsnew_0170.deprecations: diff --git a/pandas/core/common.py b/pandas/core/common.py index 990eec08d0bd6..03a4162d401a7 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -1588,7 +1588,8 @@ def backfill_2d(values, limit=None, mask=None, dtype=None): return values -def _clean_interp_method(method, order=None): +def _clean_interp_method(method, **kwargs): + order = kwargs.get('order') valid = ['linear', 'time', 'index', 'values', 'nearest', 'zero', 'slinear', 'quadratic', 'cubic', 'barycentric', 'polynomial', 'krogh', 'piecewise_polynomial', @@ -1603,7 +1604,7 @@ def _clean_interp_method(method, order=None): def interpolate_1d(xvalues, yvalues, method='linear', limit=None, - fill_value=None, bounds_error=False, order=None): + fill_value=None, bounds_error=False, order=None, **kwargs): """ Logic for the 1-d interpolation. The result should be 1-d, inputs xvalues and yvalues will each be 1-d arrays of the same length. @@ -1682,18 +1683,17 @@ def _interp_limit(invalid, limit): 'piecewise_polynomial', 'pchip'] if method in sp_methods: new_x = new_x[firstIndex:] - xvalues = xvalues[firstIndex:] result[firstIndex:][invalid] = _interpolate_scipy_wrapper( valid_x, valid_y, new_x, method=method, fill_value=fill_value, - bounds_error=bounds_error, order=order) + bounds_error=bounds_error, order=order, **kwargs) if limit: result[violate_limit] = np.nan return result def _interpolate_scipy_wrapper(x, y, new_x, method, fill_value=None, - bounds_error=False, order=None): + bounds_error=False, order=None, **kwargs): """ passed off to scipy.interpolate.interp1d. method is scipy's kind. Returns an array interpolated at new_x. Add any new methods to @@ -1734,7 +1734,7 @@ def _interpolate_scipy_wrapper(x, y, new_x, method, fill_value=None, bounds_error=bounds_error) new_y = terp(new_x) elif method == 'spline': - terp = interpolate.UnivariateSpline(x, y, k=order) + terp = interpolate.UnivariateSpline(x, y, k=order, **kwargs) new_y = terp(new_x) else: # GH 7295: need to be able to write for some reason @@ -1746,7 +1746,7 @@ def _interpolate_scipy_wrapper(x, y, new_x, method, fill_value=None, if not new_x.flags.writeable: new_x = new_x.copy() method = alt_methods[method] - new_y = method(x, y, new_x) + new_y = method(x, y, new_x, **kwargs) return new_y diff --git a/pandas/core/generic.py b/pandas/core/generic.py index b9e007a1e4d58..7d7145b88b22a 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -2896,6 +2896,7 @@ def interpolate(self, method='linear', axis=0, limit=None, inplace=False, Update the NDFrame in place if possible. downcast : optional, 'infer' or None, defaults to None Downcast dtypes if possible. + kwargs : keyword arguments to pass on to the interpolating function. Returns ------- diff --git a/pandas/tests/test_generic.py b/pandas/tests/test_generic.py index 9a8ec00188d9c..f434992e9fcd8 100644 --- a/pandas/tests/test_generic.py +++ b/pandas/tests/test_generic.py @@ -1373,6 +1373,23 @@ def test_spline(self): expected = Series([1., 2., 3., 4., 5., 6., 7.]) assert_series_equal(result, expected) + def test_spline_extrapolate(self): + tm.skip_if_no_package('scipy', '0.15', 'setting ext on scipy.interpolate.UnivariateSpline') + s = Series([1, 2, 3, 4, np.nan, 6, np.nan]) + result3 = s.interpolate(method='spline', order=1, ext=3) + expected3 = Series([1., 2., 3., 4., 5., 6., 6.]) + assert_series_equal(result3, expected3) + + result1 = s.interpolate(method='spline', order=1, ext=0) + expected1 = Series([1., 2., 3., 4., 5., 6., 7.]) + assert_series_equal(result1, expected1) + + def test_spline_smooth(self): + tm._skip_if_no_scipy() + s = Series([1, 2, np.nan, 4, 5.1, np.nan, 7]) + self.assertNotEqual(s.interpolate(method='spline', order=3, s=0)[5], + s.interpolate(method='spline', order=3)[5]) + def test_metadata_propagation_indiv(self): # groupby