{"record":{"id":"4caf0ffe893e5593","repo":"pandas-dev/pandas","slug":"cannot-convert-float-nan-to-bool","errorCode":null,"errorMessage":"cannot convert float NaN to bool","messagePattern":"cannot convert float NaN to bool","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/masked.py","lineNumber":808,"sourceCode":"\n        na_value: float | np.datetime64 | lib.NoDefault\n\n        # coerce\n        if dtype.kind == \"f\":\n            # In astype, we consider dtype=float to also mean na_value=np.nan\n            na_value = np.nan\n        elif dtype.kind == \"M\":\n            unit = np.datetime_data(dtype)[0]\n            na_value = np.datetime64(\"NaT\", unit)  # type: ignore[call-overload]\n        else:\n            na_value = lib.no_default\n\n        # to_numpy will also raise, but we get somewhat nicer exception messages here\n        if dtype.kind in \"iu\" and self._hasna:\n            raise ValueError(\"cannot convert NA to integer\")\n        if dtype.kind == \"b\" and self._hasna:\n            # careful: astype_nansafe converts np.nan to True\n            raise ValueError(\"cannot convert float NaN to bool\")\n\n        data = self.to_numpy(dtype=dtype, na_value=na_value, copy=copy)\n        return data\n\n    __array_priority__ = 1000  # higher than ndarray so ops dispatch to us\n\n    def __array__(\n        self, dtype: NpDtype | None = None, copy: bool | None = None\n    ) -> np.ndarray:\n        \"\"\"\n        the array interface, return my values\n        We return an object array here to preserve our scalar values\n        \"\"\"\n        if copy is False:\n            if not self._hasna:\n                # special case, here we can simply return the underlying data\n                result = np.array(self._data, dtype=dtype, copy=copy)\n                # If the ExtensionArray is readonly, make the numpy array readonly too","sourceCodeStart":790,"sourceCodeEnd":826,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/masked.py#L790-L826","documentation":"Raised by BaseMaskedArray.astype when the target dtype is boolean kind ('b') and the masked array has missing values. numpy's astype_nansafe converts np.nan to True, which would silently corrupt results, so pandas raises up front to surface the ambiguity.","triggerScenarios":"Calling arr.astype('bool') or arr.astype(np.bool_) on any masked ExtensionArray with self._hasna True (nullable boolean, Int, or Float with NA).","commonSituations":"Converting a nullable boolean column to numpy bool for ML features or conditional masks; coercing nullable Int/Float flags to bool after a groupby; pipelines that assume a clean boolean column.","solutions":["Cast to nullable boolean dtype: arr.astype('boolean') to preserve NA.","Decide on a sentinel first: arr.fillna(False).astype('bool') or arr.dropna().astype('bool').","Use pd.isna(arr) to build an explicit mask instead of forcing bool."],"exampleFix":"// before\narr = pd.array([True, None, False], dtype='boolean')\narr.astype('bool')   # raises\n// after\narr.fillna(False).astype('bool')","handlingStrategy":"validation","validationCode":"if dtype.kind == 'b' and arr._hasna:\n    raise ValueError('Refusing bool cast with NA; fill or drop first')\nout = arr.astype(dtype)","typeGuard":"def can_astype_bool(arr) -> bool:\n    return not arr._hasna","tryCatchPattern":"try:\n    out = arr.astype('bool')\nexcept ValueError as e:\n    if 'NaN to bool' in str(e):\n        out = arr.fillna(False).astype('bool')\n    else:\n        raise","preventionTips":["Use 'boolean' (nullable) when NAs must be preserved.","Decide on a fill policy (False/True) at one boundary, not scattered through the pipeline.","Test nullable input columns for NAs before forcing numpy bool."],"tags":["pandas","masked-array","astype","na-value","boolean"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}