From a60b481f78a26b6c28d97c8a00368994f84b7b03 Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 26 Jun 2023 16:06:01 -0700 Subject: [PATCH 1/2] CLN: unused args in pad_or_backfill --- pandas/core/arrays/datetimelike.py | 2 - pandas/core/arrays/numpy_.py | 2 - pandas/core/generic.py | 38 ++++++++++--------- pandas/core/internals/blocks.py | 13 ------- .../tests/series/methods/test_interpolate.py | 2 +- 5 files changed, 22 insertions(+), 35 deletions(-) diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 48c9305cf2ccc..f13a5e8b560a4 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -2239,7 +2239,6 @@ def interpolate( limit, limit_direction, limit_area, - fill_value, inplace: bool, **kwargs, ) -> Self: @@ -2263,7 +2262,6 @@ def interpolate( limit=limit, limit_direction=limit_direction, limit_area=limit_area, - fill_value=fill_value, **kwargs, ) if inplace: diff --git a/pandas/core/arrays/numpy_.py b/pandas/core/arrays/numpy_.py index 6d60657c3100b..8b6e49ccf2d41 100644 --- a/pandas/core/arrays/numpy_.py +++ b/pandas/core/arrays/numpy_.py @@ -267,7 +267,6 @@ def interpolate( limit, limit_direction, limit_area, - fill_value, inplace: bool, **kwargs, ) -> Self: @@ -289,7 +288,6 @@ def interpolate( limit=limit, limit_direction=limit_direction, limit_area=limit_area, - fill_value=fill_value, **kwargs, ) if inplace: diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 033265b1f373e..041bc33634850 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -6891,7 +6891,7 @@ def _deprecate_downcast(self, downcast) -> None: ) @final - def _fillna_with_method( + def _pad_or_backfill( self, method: Literal["ffill", "bfill", "pad", "backfill"], *, @@ -6908,7 +6908,7 @@ def _fillna_with_method( if not self._mgr.is_single_block and axis == 1: if inplace: raise NotImplementedError() - result = self.T._fillna_with_method(method=method, limit=limit).T + result = self.T._pad_or_backfill(method=method, limit=limit).T return result @@ -7105,8 +7105,8 @@ def fillna( axis = self._get_axis_number(axis) if value is None: - return self._fillna_with_method( - # error: Argument 1 to "_fillna_with_method" of "NDFrame" has + return self._pad_or_backfill( + # error: Argument 1 to "_pad_or_backfill" of "NDFrame" has # incompatible type "Optional[Literal['backfill', 'bfill', 'ffill', # 'pad']]"; expected "Literal['ffill', 'bfill', 'pad', 'backfill']" method, # type: ignore[arg-type] @@ -7311,7 +7311,7 @@ def ffill( """ self._deprecate_downcast(downcast) - return self._fillna_with_method( + return self._pad_or_backfill( "ffill", axis=axis, inplace=inplace, limit=limit, downcast=downcast ) @@ -7443,7 +7443,7 @@ def bfill( 3 4.0 7 """ self._deprecate_downcast(downcast) - return self._fillna_with_method( + return self._pad_or_backfill( "bfill", axis=axis, inplace=inplace, limit=limit, downcast=downcast ) @@ -7994,8 +7994,6 @@ def interpolate( "Only `method=linear` interpolation is supported on MultiIndexes." ) - limit_direction = missing.infer_limit_direction(limit_direction, method) - if obj.ndim == 2 and np.all(obj.dtypes == np.dtype("object")): raise TypeError( "Cannot interpolate with all object-dtype columns " @@ -8003,22 +8001,28 @@ def interpolate( "column to a numeric dtype." ) - index = missing.get_interp_index(method, obj.index) + if "fill_value" in kwargs: + raise ValueError( + "'fill_value' is not a valid keyword for " + f"{type(self).__name__}.interpolate" + ) if method.lower() in fillna_methods: # TODO(3.0): remove this case + # TODO: warn/raise on limit_direction or kwargs which are ignored? + # as of 2023-06-26 no tests get here with either + new_data = obj._mgr.pad_or_backfill( method=method, axis=axis, - index=index, limit=limit, - limit_direction=limit_direction, limit_area=limit_area, inplace=inplace, downcast=downcast, - **kwargs, ) else: + limit_direction = missing.infer_limit_direction(limit_direction, method) + index = missing.get_interp_index(method, obj.index) axis = self._info_axis_number new_data = obj._mgr.interpolate( method=method, @@ -9980,8 +9984,8 @@ def _align_frame( ) if method is not None: - left = left._fillna_with_method(method, axis=fill_axis, limit=limit) - right = right._fillna_with_method(method, axis=fill_axis, limit=limit) + left = left._pad_or_backfill(method, axis=fill_axis, limit=limit) + right = right._pad_or_backfill(method, axis=fill_axis, limit=limit) return left, right, join_index @@ -10057,8 +10061,8 @@ def _align_series( if fill_na: fill_value, method = validate_fillna_kwargs(fill_value, method) if method is not None: - left = left._fillna_with_method(method, limit=limit, axis=fill_axis) - right = right._fillna_with_method(method, limit=limit) + left = left._pad_or_backfill(method, limit=limit, axis=fill_axis) + right = right._pad_or_backfill(method, limit=limit) else: left = left.fillna(fill_value, limit=limit, axis=fill_axis) right = right.fillna(fill_value, limit=limit) @@ -11474,7 +11478,7 @@ def pct_change( if fill_method is None: data = self else: - data = self._fillna_with_method(fill_method, axis=axis, limit=limit) + data = self._pad_or_backfill(fill_method, axis=axis, limit=limit) shifted = data.shift(periods=periods, freq=freq, axis=axis, **kwargs) # Unsupported left operand type for / ("Self") diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 9f1767befd18a..c0195189a3d6e 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1348,12 +1348,9 @@ def pad_or_backfill( *, method: FillnaOptions = "pad", axis: AxisInt = 0, - index: Index | None = None, inplace: bool = False, limit: int | None = None, - limit_direction: Literal["forward", "backward", "both"] = "forward", limit_area: Literal["inside", "outside"] | None = None, - fill_value: Any | None = None, downcast: Literal["infer"] | None = None, using_cow: bool = False, **kwargs, @@ -1361,12 +1358,9 @@ def pad_or_backfill( return self.interpolate( method=method, axis=axis, - index=index, inplace=inplace, limit=limit, - limit_direction=limit_direction, limit_area=limit_area, - fill_value=fill_value, downcast=downcast, using_cow=using_cow, **kwargs, @@ -1382,7 +1376,6 @@ def interpolate( limit: int | None = None, limit_direction: Literal["forward", "backward", "both"] = "forward", limit_area: Literal["inside", "outside"] | None = None, - fill_value: Any | None = None, downcast: Literal["infer"] | None = None, using_cow: bool = False, **kwargs, @@ -1424,7 +1417,6 @@ def interpolate( limit=limit, limit_direction=limit_direction, limit_area=limit_area, - fill_value=fill_value, downcast=downcast, **kwargs, ) @@ -1440,10 +1432,6 @@ def interpolate( # Dispatch to the PandasArray method. # We know self.array_values is a PandasArray bc EABlock overrides if m is not None: - if fill_value is not None: - # similar to validate_fillna_kwargs - raise ValueError("Cannot pass both fill_value and method") - # TODO: warn about ignored kwargs, limit_direction, index...? new_values = cast(PandasArray, self.array_values).pad_or_backfill( method=method, @@ -1461,7 +1449,6 @@ def interpolate( limit=limit, limit_direction=limit_direction, limit_area=limit_area, - fill_value=fill_value, inplace=arr_inplace, **kwargs, ) diff --git a/pandas/tests/series/methods/test_interpolate.py b/pandas/tests/series/methods/test_interpolate.py index 8c4c5524ac3be..abd4cec5ad45c 100644 --- a/pandas/tests/series/methods/test_interpolate.py +++ b/pandas/tests/series/methods/test_interpolate.py @@ -361,7 +361,7 @@ def test_interp_invalid_method_and_value(self): # GH#36624 ser = Series([1, 3, np.nan, 12, np.nan, 25]) - msg = "Cannot pass both fill_value and method" + msg = "'fill_value' is not a valid keyword for Series.interpolate" msg2 = "Series.interpolate with method=pad" with pytest.raises(ValueError, match=msg): with tm.assert_produces_warning(FutureWarning, match=msg2): From 161fd59797371287aa3fdd6fe600261f131fb46c Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 26 Jun 2023 19:38:22 -0700 Subject: [PATCH 2/2] restore limit_direction validation --- pandas/core/generic.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 041bc33634850..b233966a77293 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -7994,6 +7994,8 @@ def interpolate( "Only `method=linear` interpolation is supported on MultiIndexes." ) + limit_direction = missing.infer_limit_direction(limit_direction, method) + if obj.ndim == 2 and np.all(obj.dtypes == np.dtype("object")): raise TypeError( "Cannot interpolate with all object-dtype columns " @@ -8021,7 +8023,6 @@ def interpolate( downcast=downcast, ) else: - limit_direction = missing.infer_limit_direction(limit_direction, method) index = missing.get_interp_index(method, obj.index) axis = self._info_axis_number new_data = obj._mgr.interpolate(