From 276f16da76db5abfd971f62c353bef158031ba53 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sat, 2 Nov 2019 12:48:22 -0700 Subject: [PATCH] CLN: requested follow-ups (#29360) * follow-up to #29314 * followup to #28289 --- pandas/_libs/algos.pyx | 12 +++++++++++ pandas/core/internals/blocks.py | 7 ++---- pandas/core/missing.py | 9 +------- pandas/tests/reductions/test_reductions.py | 25 ++++++++++++++-------- 4 files changed, 31 insertions(+), 22 deletions(-) diff --git a/pandas/_libs/algos.pyx b/pandas/_libs/algos.pyx index e3c7fef6f048f..a08ae66865e20 100644 --- a/pandas/_libs/algos.pyx +++ b/pandas/_libs/algos.pyx @@ -380,6 +380,18 @@ ctypedef fused algos_t: def _validate_limit(nobs: int, limit=None) -> int: + """ + Check that the `limit` argument is a positive integer. + + Parameters + ---------- + nobs : int + limit : object + + Returns + ------- + int + """ if limit is None: lim = nobs else: diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 51108d9a5a573..448d2faf8b85f 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -7,7 +7,7 @@ import numpy as np -from pandas._libs import NaT, lib, tslib, writers +from pandas._libs import NaT, algos as libalgos, lib, tslib, writers from pandas._libs.index import convert_scalar import pandas._libs.internals as libinternals from pandas._libs.tslibs import Timedelta, conversion @@ -393,10 +393,7 @@ def fillna(self, value, limit=None, inplace=False, downcast=None): mask = isna(self.values) if limit is not None: - if not is_integer(limit): - raise ValueError("Limit must be an integer") - if limit < 1: - raise ValueError("Limit must be greater than 0") + limit = libalgos._validate_limit(None, limit=limit) mask[mask.cumsum(self.ndim - 1) > limit] = False if not self._can_hold_na: diff --git a/pandas/core/missing.py b/pandas/core/missing.py index f2655c126b9e5..5a1bf6d37b081 100644 --- a/pandas/core/missing.py +++ b/pandas/core/missing.py @@ -11,7 +11,6 @@ ensure_float64, is_datetime64_dtype, is_datetime64tz_dtype, - is_integer, is_integer_dtype, is_numeric_v_string_like, is_scalar, @@ -191,13 +190,7 @@ def interpolate_1d( ) # default limit is unlimited GH #16282 - if limit is None: - # limit = len(xvalues) - pass - elif not is_integer(limit): - raise ValueError("Limit must be an integer") - elif limit < 1: - raise ValueError("Limit must be greater than 0") + limit = algos._validate_limit(nobs=None, limit=limit) from pandas import Series diff --git a/pandas/tests/reductions/test_reductions.py b/pandas/tests/reductions/test_reductions.py index a04f8f0df1151..4dfe561831ced 100644 --- a/pandas/tests/reductions/test_reductions.py +++ b/pandas/tests/reductions/test_reductions.py @@ -299,15 +299,6 @@ def test_timedelta_ops(self): result = td.to_frame().std() assert result[0] == expected - # invalid ops - for op in ["skew", "kurt", "sem", "prod", "var"]: - msg = "reduction operation '{}' not allowed for this dtype" - with pytest.raises(TypeError, match=msg.format(op)): - getattr(td, op)() - - with pytest.raises(TypeError, match=msg.format(op)): - getattr(td.to_frame(), op)(numeric_only=False) - # GH#10040 # make sure NaT is properly handled by median() s = Series([Timestamp("2015-02-03"), Timestamp("2015-02-07")]) @@ -318,6 +309,22 @@ def test_timedelta_ops(self): ) assert s.diff().median() == timedelta(days=6) + @pytest.mark.parametrize("opname", ["skew", "kurt", "sem", "prod", "var"]) + def test_invalid_td64_reductions(self, opname): + s = Series( + [Timestamp("20130101") + timedelta(seconds=i * i) for i in range(10)] + ) + td = s.diff() + + msg = "reduction operation '{op}' not allowed for this dtype" + msg = msg.format(op=opname) + + with pytest.raises(TypeError, match=msg): + getattr(td, opname)() + + with pytest.raises(TypeError, match=msg): + getattr(td.to_frame(), opname)(numeric_only=False) + def test_minmax_tz(self, tz_naive_fixture): tz = tz_naive_fixture # monotonic