import math import numbers from contextlib import suppress def is_scalar_nan(x): """Test if x is NaN. This function is meant to overcome the issue that np.isnan does not allow non-numerical types as input, and that np.nan is not float('nan'). Parameters ---------- x : any type Any scalar value. Returns ------- bool Returns true if x is NaN, and false otherwise. Examples -------- >>> import numpy as np >>> from sklearn.utils._missing import is_scalar_nan >>> is_scalar_nan(np.nan) True >>> is_scalar_nan(float("nan")) True >>> is_scalar_nan(None) False >>> is_scalar_nan("") False >>> is_scalar_nan([np.nan]) False """ return ( not isinstance(x, numbers.Integral) and isinstance(x, numbers.Real) and math.isnan(x) ) def is_pandas_na(x): """Test if x is pandas.NA. We intentionally do not use this function to return `True` for `pd.NA` in `is_scalar_nan`, because estimators that support `pd.NA` are the exception rather than the rule at the moment. When `pd.NA` is more universally supported, we may reconsider this decision. Parameters ---------- x : any type Returns ------- boolean """ with suppress(ImportError): from pandas import NA return x is NA return False