Repository: pandas-dev/pandas

Issue:
Pass through the kwargs to the various interpolators
Many of the interpolators have additional arguments so why not pass the `kwargs` collected by [`interpolate`](http://pandas.pydata.org/pandas-docs/dev/generated/pandas.Series.interpolate.html) function to the underlying interpolators?

For example the [spline](https://github.com/pydata/pandas/blob/821542fb1dfd55b0e0d25e55eb4fee6555d01cbd/pandas/core/common.py#L1737) function can also take a smoothing factor `s`.



Discussion:

Resolving patch:
diff --git a/pandas/core/common.py b/pandas/core/common.py
--- 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
--- 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
         -------


Test patch:
diff --git a/pandas/tests/test_generic.py b/pandas/tests/test_generic.py
--- 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