Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: Fix exceptions when Series.interpolate's order parameter is missing or invalid #25246

Merged
7 changes: 2 additions & 5 deletions pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1115,11 +1115,8 @@ def check_int_bool(self, inplace):
fill_value=fill_value,
coerce=coerce,
downcast=downcast)
# try an interp method
try:
m = missing.clean_interp_method(method, **kwargs)
except ValueError:
m = None
# validate the interp method
m = missing.clean_interp_method(method, **kwargs)

gfyoung marked this conversation as resolved.
Show resolved Hide resolved
if m is not None:
r = check_int_bool(self, inplace)
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/missing.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,8 @@ def _interpolate_scipy_wrapper(x, y, new_x, method, fill_value=None,
bounds_error=bounds_error)
new_y = terp(new_x)
elif method == 'spline':
# GH #10633
if not order:
# GH #10633, #24014
if order is None or not (0 < order):
gfyoung marked this conversation as resolved.
Show resolved Hide resolved
raise ValueError("order needs to be specified and greater than 0")
terp = interpolate.UnivariateSpline(x, y, k=order, **kwargs)
new_y = terp(new_x)
Expand Down
30 changes: 22 additions & 8 deletions pandas/tests/series/test_missing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1064,19 +1064,32 @@ def test_interp_limit(self):
# GH 9217, make sure limit is an int and greater than 0
methods = ['linear', 'time', 'index', 'values', 'nearest', 'zero',
'slinear', 'quadratic', 'cubic', 'barycentric', 'krogh',
'polynomial', 'spline', 'piecewise_polynomial', None,
'polynomial', 'spline', 'piecewise_polynomial',
gfyoung marked this conversation as resolved.
Show resolved Hide resolved
'from_derivatives', 'pchip', 'akima']
s = pd.Series([1, 2, np.nan, np.nan, 5])
msg = (r"Limit must be greater than 0|"
"time-weighted interpolation only works on Series or"
r" DataFrames with a DatetimeIndex|"
r"invalid method '(polynomial|spline|None)' to interpolate|"
"Limit must be an integer")
r"Limit must be an integer|"
r"You must specify the order of the spline")
for limit in [-1, 0, 1., 2.]:
for method in methods:
with pytest.raises(ValueError, match=msg):
s.interpolate(limit=limit, method=method)
Copy link
Member

@gfyoung gfyoung Feb 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While we can, let's do same thing here: break up this test so that we can leverage pytest parameterization.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with you that this test ought to be broken up and simplified.

I will try to do that tonight, but if it proves difficult, I may propose doing it in a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, ready for another look.


def test_interp_invalid_method(self):
s = Series([1, 3, np.nan, 12, np.nan, 25])

invalid_methods = [None, 'nonexistent_method']
for method in invalid_methods:
msg = "method must be one of.*\\. Got '{}' instead".format(method)
with pytest.raises(ValueError, match=msg):
s.interpolate(method=method)
# When an invalid method and invalid limit (such as -1) are
# provided, the error message reflects the invalid method.
with pytest.raises(ValueError, match=msg):
s.interpolate(method=method, limit=-1)

def test_interp_limit_forward(self):
s = Series([1, 3, np.nan, np.nan, np.nan, 11])

Expand Down Expand Up @@ -1277,7 +1290,7 @@ def test_interp_limit_no_nans(self):
@pytest.mark.parametrize("method", ['polynomial', 'spline'])
def test_no_order(self, method):
s = Series([0, 1, np.nan, 3])
msg = "invalid method '{}' to interpolate".format(method)
msg = "You must specify the order of the spline or polynomial"
with pytest.raises(ValueError, match=msg):
s.interpolate(method=method)

Expand Down Expand Up @@ -1315,16 +1328,17 @@ def test_spline_interpolation(self):

@td.skip_if_no_scipy
def test_spline_error(self):
# see gh-10633
# see GH-10633, GH-24014
s = pd.Series(np.arange(10) ** 2)
s[np.random.randint(0, 9, 3)] = np.nan
msg = "invalid method 'spline' to interpolate"
msg = "You must specify the order of the spline or polynomial"
with pytest.raises(ValueError, match=msg):
s.interpolate(method='spline')

msg = "order needs to be specified and greater than 0"
with pytest.raises(ValueError, match=msg):
s.interpolate(method='spline', order=0)
for invalid_order in [-1, -1., 0, 0., np.nan]:
with pytest.raises(ValueError, match=msg):
s.interpolate(method='spline', order=invalid_order)
gfyoung marked this conversation as resolved.
Show resolved Hide resolved

def test_interp_timedelta64(self):
# GH 6424
Expand Down