Skip to content

Commit 4d0f179

Browse files
authored
REF/CLN: Parametrize _isna (#33835)
1 parent 541a357 commit 4d0f179

File tree

1 file changed

+27
-43
lines changed

1 file changed

+27
-43
lines changed

pandas/core/dtypes/missing.py

+27-43
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""
22
missing types & inference
33
"""
4+
from functools import partial
5+
46
import numpy as np
57

68
from pandas._config import get_option
@@ -124,61 +126,44 @@ def isna(obj):
124126
isnull = isna
125127

126128

127-
def _isna_new(obj):
128-
129-
if is_scalar(obj):
130-
return libmissing.checknull(obj)
131-
# hack (for now) because MI registers as ndarray
132-
elif isinstance(obj, ABCMultiIndex):
133-
raise NotImplementedError("isna is not defined for MultiIndex")
134-
elif isinstance(obj, type):
135-
return False
136-
elif isinstance(obj, (ABCSeries, np.ndarray, ABCIndexClass, ABCExtensionArray)):
137-
return _isna_ndarraylike(obj, old=False)
138-
elif isinstance(obj, ABCDataFrame):
139-
return obj.isna()
140-
elif isinstance(obj, list):
141-
return _isna_ndarraylike(np.asarray(obj, dtype=object), old=False)
142-
elif hasattr(obj, "__array__"):
143-
return _isna_ndarraylike(np.asarray(obj), old=False)
144-
else:
145-
return False
146-
147-
148-
def _isna_old(obj):
129+
def _isna(obj, inf_as_na: bool = False):
149130
"""
150-
Detect missing values, treating None, NaN, INF, -INF as null.
131+
Detect missing values, treating None, NaN or NA as null. Infinite
132+
values will also be treated as null if inf_as_na is True.
151133
152134
Parameters
153135
----------
154-
arr: ndarray or object value
136+
obj: ndarray or object value
137+
Input array or scalar value.
138+
inf_as_na: bool
139+
Whether to treat infinity as null.
155140
156141
Returns
157142
-------
158143
boolean ndarray or boolean
159144
"""
160145
if is_scalar(obj):
161-
return libmissing.checknull_old(obj)
146+
if inf_as_na:
147+
return libmissing.checknull_old(obj)
148+
else:
149+
return libmissing.checknull(obj)
162150
# hack (for now) because MI registers as ndarray
163151
elif isinstance(obj, ABCMultiIndex):
164152
raise NotImplementedError("isna is not defined for MultiIndex")
165153
elif isinstance(obj, type):
166154
return False
167155
elif isinstance(obj, (ABCSeries, np.ndarray, ABCIndexClass, ABCExtensionArray)):
168-
return _isna_ndarraylike(obj, old=True)
156+
return _isna_ndarraylike(obj, inf_as_na=inf_as_na)
169157
elif isinstance(obj, ABCDataFrame):
170158
return obj.isna()
171159
elif isinstance(obj, list):
172-
return _isna_ndarraylike(np.asarray(obj, dtype=object), old=True)
160+
return _isna_ndarraylike(np.asarray(obj, dtype=object), inf_as_na=inf_as_na)
173161
elif hasattr(obj, "__array__"):
174-
return _isna_ndarraylike(np.asarray(obj), old=True)
162+
return _isna_ndarraylike(np.asarray(obj), inf_as_na=inf_as_na)
175163
else:
176164
return False
177165

178166

179-
_isna = _isna_new
180-
181-
182167
def _use_inf_as_na(key):
183168
"""
184169
Option change callback for na/inf behaviour.
@@ -200,22 +185,19 @@ def _use_inf_as_na(key):
200185
* https://stackoverflow.com/questions/4859217/
201186
programmatically-creating-variables-in-python/4859312#4859312
202187
"""
203-
flag = get_option(key)
204-
if flag:
205-
globals()["_isna"] = _isna_old
206-
else:
207-
globals()["_isna"] = _isna_new
188+
inf_as_na = get_option(key)
189+
globals()["_isna"] = partial(_isna, inf_as_na=inf_as_na)
208190

209191

210-
def _isna_ndarraylike(obj, old: bool = False):
192+
def _isna_ndarraylike(obj, inf_as_na: bool = False):
211193
"""
212194
Return an array indicating which values of the input array are NaN / NA.
213195
214196
Parameters
215197
----------
216198
obj: array-like
217199
The input array whose elements are to be checked.
218-
old: bool
200+
inf_as_na: bool
219201
Whether or not to treat infinite values as NA.
220202
221203
Returns
@@ -227,17 +209,17 @@ def _isna_ndarraylike(obj, old: bool = False):
227209
dtype = values.dtype
228210

229211
if is_extension_array_dtype(dtype):
230-
if old:
212+
if inf_as_na:
231213
result = values.isna() | (values == -np.inf) | (values == np.inf)
232214
else:
233215
result = values.isna()
234216
elif is_string_dtype(dtype):
235-
result = _isna_string_dtype(values, dtype, old=old)
217+
result = _isna_string_dtype(values, dtype, inf_as_na=inf_as_na)
236218
elif needs_i8_conversion(dtype):
237219
# this is the NaT pattern
238220
result = values.view("i8") == iNaT
239221
else:
240-
if old:
222+
if inf_as_na:
241223
result = ~np.isfinite(values)
242224
else:
243225
result = np.isnan(values)
@@ -249,15 +231,17 @@ def _isna_ndarraylike(obj, old: bool = False):
249231
return result
250232

251233

252-
def _isna_string_dtype(values: np.ndarray, dtype: np.dtype, old: bool) -> np.ndarray:
234+
def _isna_string_dtype(
235+
values: np.ndarray, dtype: np.dtype, inf_as_na: bool
236+
) -> np.ndarray:
253237
# Working around NumPy ticket 1542
254238
shape = values.shape
255239

256240
if is_string_like_dtype(dtype):
257241
result = np.zeros(values.shape, dtype=bool)
258242
else:
259243
result = np.empty(shape, dtype=bool)
260-
if old:
244+
if inf_as_na:
261245
vec = libmissing.isnaobj_old(values.ravel())
262246
else:
263247
vec = libmissing.isnaobj(values.ravel())

0 commit comments

Comments
 (0)