Skip to content

Commit 5b332e4

Browse files
jbrockmendeljreback
authored andcommitted
REF: avoid core.missing dependency on Series (#29400)
1 parent d31e94b commit 5b332e4

File tree

2 files changed

+43
-25
lines changed

2 files changed

+43
-25
lines changed

pandas/core/generic.py

+4-19
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
from pandas.core.indexes.period import Period, PeriodIndex
8484
import pandas.core.indexing as indexing
8585
from pandas.core.internals import BlockManager
86+
from pandas.core.missing import find_valid_index
8687
from pandas.core.ops import _align_method_FRAME
8788

8889
from pandas.io.formats import format as fmt
@@ -10870,27 +10871,11 @@ def _find_valid_index(self, how: str):
1087010871
-------
1087110872
idx_first_valid : type of index
1087210873
"""
10873-
assert how in ["first", "last"]
1087410874

10875-
if len(self) == 0: # early stop
10875+
idxpos = find_valid_index(self._values, how)
10876+
if idxpos is None:
1087610877
return None
10877-
is_valid = ~self.isna()
10878-
10879-
if self.ndim == 2:
10880-
is_valid = is_valid.any(1) # reduce axis 1
10881-
10882-
if how == "first":
10883-
idxpos = is_valid.values[::].argmax()
10884-
10885-
if how == "last":
10886-
idxpos = len(self) - 1 - is_valid.values[::-1].argmax()
10887-
10888-
chk_notna = is_valid.iat[idxpos]
10889-
idx = self.index[idxpos]
10890-
10891-
if not chk_notna:
10892-
return None
10893-
return idx
10878+
return self.index[idxpos]
1089410879

1089510880
@Appender(
1089610881
_shared_docs["valid_index"] % {"position": "first", "klass": "Series/DataFrame"}

pandas/core/missing.py

+39-6
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,43 @@ def clean_interp_method(method, **kwargs):
128128
return method
129129

130130

131+
def find_valid_index(values, how: str):
132+
"""
133+
Retrieves the index of the first valid value.
134+
135+
Parameters
136+
----------
137+
values : ndarray or ExtensionArray
138+
how : {'first', 'last'}
139+
Use this parameter to change between the first or last valid index.
140+
141+
Returns
142+
-------
143+
int or None
144+
"""
145+
assert how in ["first", "last"]
146+
147+
if len(values) == 0: # early stop
148+
return None
149+
150+
is_valid = ~isna(values)
151+
152+
if values.ndim == 2:
153+
is_valid = is_valid.any(1) # reduce axis 1
154+
155+
if how == "first":
156+
idxpos = is_valid[::].argmax()
157+
158+
if how == "last":
159+
idxpos = len(values) - 1 - is_valid[::-1].argmax()
160+
161+
chk_notna = is_valid[idxpos]
162+
163+
if not chk_notna:
164+
return None
165+
return idxpos
166+
167+
131168
def interpolate_1d(
132169
xvalues,
133170
yvalues,
@@ -192,14 +229,10 @@ def interpolate_1d(
192229
# default limit is unlimited GH #16282
193230
limit = algos._validate_limit(nobs=None, limit=limit)
194231

195-
from pandas import Series
196-
197-
ys = Series(yvalues)
198-
199232
# These are sets of index pointers to invalid values... i.e. {0, 1, etc...
200233
all_nans = set(np.flatnonzero(invalid))
201-
start_nans = set(range(ys.first_valid_index()))
202-
end_nans = set(range(1 + ys.last_valid_index(), len(valid)))
234+
start_nans = set(range(find_valid_index(yvalues, "first")))
235+
end_nans = set(range(1 + find_valid_index(yvalues, "last"), len(valid)))
203236
mid_nans = all_nans - start_nans - end_nans
204237

205238
# Like the sets above, preserve_nans contains indices of invalid values,

0 commit comments

Comments
 (0)