diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 0be840f9a4ef1..a8a3bf3fc532e 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -6876,7 +6876,7 @@ def _fillna_with_method( return result - new_mgr = self._mgr.interpolate( + new_mgr = self._mgr.pad_or_backfill( method=method, axis=axis, limit=limit, @@ -7957,9 +7957,6 @@ def interpolate( stacklevel=find_stack_level(), ) - if method not in fillna_methods: - axis = self._info_axis_number - if isinstance(obj.index, MultiIndex) and method != "linear": raise ValueError( "Only `method=linear` interpolation is supported on MultiIndexes." @@ -7976,17 +7973,32 @@ def interpolate( index = missing.get_interp_index(method, obj.index) - new_data = obj._mgr.interpolate( - method=method, - axis=axis, - index=index, - limit=limit, - limit_direction=limit_direction, - limit_area=limit_area, - inplace=inplace, - downcast=downcast, - **kwargs, - ) + if method.lower() in fillna_methods: + # TODO(3.0): remove this case + 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: + axis = self._info_axis_number + new_data = obj._mgr.interpolate( + method=method, + axis=axis, + index=index, + limit=limit, + limit_direction=limit_direction, + limit_area=limit_area, + inplace=inplace, + downcast=downcast, + **kwargs, + ) result = self._constructor(new_data) if should_transpose: diff --git a/pandas/core/internals/array_manager.py b/pandas/core/internals/array_manager.py index 098a78fc54b71..e544034ea5894 100644 --- a/pandas/core/internals/array_manager.py +++ b/pandas/core/internals/array_manager.py @@ -357,6 +357,9 @@ def diff(self, n: int, axis: AxisInt) -> Self: assert self.ndim == 2 and axis == 0 # caller ensures return self.apply(algos.diff, n=n, axis=axis) + def pad_or_backfill(self, **kwargs) -> Self: + return self.apply_with_block("pad_or_backfill", swap_axis=False, **kwargs) + def interpolate(self, **kwargs) -> Self: return self.apply_with_block("interpolate", swap_axis=False, **kwargs) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index ae820a40005df..6f92dd77908c9 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1343,6 +1343,35 @@ def fillna( ] ) + def pad_or_backfill( + self, + *, + 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: str | None = None, + fill_value: Any | None = None, + downcast: Literal["infer"] | None = None, + using_cow: bool = False, + **kwargs, + ) -> list[Block]: + 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, + ) + def interpolate( self, *, diff --git a/pandas/core/internals/managers.py b/pandas/core/internals/managers.py index bb745f61ab221..292f5b2344227 100644 --- a/pandas/core/internals/managers.py +++ b/pandas/core/internals/managers.py @@ -416,6 +416,14 @@ def diff(self, n: int, axis: AxisInt) -> Self: axis = self._normalize_axis(axis) return self.apply("diff", n=n, axis=axis) + def pad_or_backfill(self, inplace: bool, **kwargs) -> Self: + return self.apply( + "pad_or_backfill", + inplace=inplace, + **kwargs, + using_cow=using_copy_on_write(), + ) + def interpolate(self, inplace: bool, **kwargs) -> Self: return self.apply( "interpolate", inplace=inplace, **kwargs, using_cow=using_copy_on_write()