diff --git a/pandas/core/generic.py b/pandas/core/generic.py index a4d99cb0eca42..9534eca51f383 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -11643,7 +11643,7 @@ def _find_valid_index(self, *, how: str) -> Hashable | None: ------- idx_first_valid : type of index """ - idxpos = find_valid_index(self._values, how=how) + idxpos = find_valid_index(self._values, how=how, is_valid=~isna(self._values)) if idxpos is None: return None return self.index[idxpos] diff --git a/pandas/core/missing.py b/pandas/core/missing.py index 0d058ead9d22c..0da4f6404c3cc 100644 --- a/pandas/core/missing.py +++ b/pandas/core/missing.py @@ -170,7 +170,9 @@ def clean_interp_method(method: str, index: Index, **kwargs) -> str: return method -def find_valid_index(values, *, how: str) -> int | None: +def find_valid_index( + values, *, how: str, is_valid: npt.NDArray[np.bool_] +) -> int | None: """ Retrieves the index of the first valid value. @@ -179,6 +181,8 @@ def find_valid_index(values, *, how: str) -> int | None: values : ndarray or ExtensionArray how : {'first', 'last'} Use this parameter to change between the first or last valid index. + is_valid: np.ndarray + Mask to find na_values. Returns ------- @@ -189,8 +193,6 @@ def find_valid_index(values, *, how: str) -> int | None: if len(values) == 0: # early stop return None - is_valid = ~isna(values) - if values.ndim == 2: is_valid = is_valid.any(axis=1) # reduce axis 1 @@ -204,7 +206,9 @@ def find_valid_index(values, *, how: str) -> int | None: if not chk_notna: return None - return idxpos + # Incompatible return value type (got "signedinteger[Any]", + # expected "Optional[int]") + return idxpos # type: ignore[return-value] def interpolate_array_2d( @@ -400,12 +404,12 @@ def _interpolate_1d( # These are sets of index pointers to invalid values... i.e. {0, 1, etc... all_nans = set(np.flatnonzero(invalid)) - first_valid_index = find_valid_index(yvalues, how="first") + first_valid_index = find_valid_index(yvalues, how="first", is_valid=valid) if first_valid_index is None: # no nan found in start first_valid_index = 0 start_nans = set(range(first_valid_index)) - last_valid_index = find_valid_index(yvalues, how="last") + last_valid_index = find_valid_index(yvalues, how="last", is_valid=valid) if last_valid_index is None: # no nan found in end last_valid_index = len(yvalues) end_nans = set(range(1 + last_valid_index, len(valid))) @@ -738,12 +742,13 @@ def _interpolate_with_limit_area( """ invalid = isna(values) + is_valid = ~invalid if not invalid.all(): - first = find_valid_index(values, how="first") + first = find_valid_index(values, how="first", is_valid=is_valid) if first is None: first = 0 - last = find_valid_index(values, how="last") + last = find_valid_index(values, how="last", is_valid=is_valid) if last is None: last = len(values)