diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index c62be4f767f00..1b9322d5049c5 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1,4 +1,5 @@ from datetime import datetime, timedelta +import functools import inspect import re from typing import TYPE_CHECKING, Any, List, Optional @@ -1127,6 +1128,7 @@ def interpolate( axis=axis, inplace=inplace, limit=limit, + limit_area=limit_area, fill_value=fill_value, coerce=coerce, downcast=downcast, @@ -1155,6 +1157,7 @@ def _interpolate_with_fill( axis: int = 0, inplace: bool = False, limit: Optional[int] = None, + limit_area: Optional[str] = None, fill_value: Optional[Any] = None, coerce: bool = False, downcast: Optional[str] = None, @@ -1176,15 +1179,42 @@ def _interpolate_with_fill( # We only get here for non-ExtensionBlock fill_value = convert_scalar_for_putitemlike(fill_value, self.values.dtype) - values = missing.interpolate_2d( - values, + interpolate_2d = functools.partial( + missing.interpolate_2d, method=method, - axis=axis, limit=limit, fill_value=fill_value, dtype=self.dtype, ) + if limit_area is None: + values = interpolate_2d(values, axis=axis) + else: + def func(values): + invalid = isna(values) + + if not invalid.any(): + return values + + if not invalid.all(): + first = missing.find_valid_index(values, "first") + last = missing.find_valid_index(values, "last") + + values = interpolate_2d(values) + + if limit_area == "inside": + invalid[first : last + 1] = False + elif limit_area == "outside": + invalid[:first] = False + invalid[last + 1 :] = False + + values[invalid] = np.nan + else: + values = interpolate_2d(values) + return values + + values = np.apply_along_axis(func, axis, values) + blocks = [self.make_block_same_class(values, ndim=self.ndim)] return self._maybe_downcast(blocks, downcast)