{"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/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/masked.py#L790-L826","documentation":"Raised by BaseMaskedArray._astype when casting a masked array with missing values to a bool numpy dtype. numpy's astype_nansafe would convert np.nan to True, which is wrong, so pandas refuses up front. A compatible na_value must be supplied (e.g. False) or NAs removed first.","triggerScenarios":"Calling arr.astype('bool') / arr.astype(bool) / np.asarray(arr, dtype=bool) on a BaseMaskedArray that has any missing values.","commonSituations":"Converting a nullable numeric column to a boolean mask while the column still has NaNs; building a truth array from a nullable Series for indexing.","solutions":["Drop or impute missing values first: arr.dropna().astype('bool') or arr.fillna(False).astype('bool').","Convert via to_numpy with an explicit na_value: arr.to_numpy(dtype='bool', na_value=False).","Use a nullable Boolean dtype if NA must be preserved: arr.astype('boolean')."],"exampleFix":"// before\ns.astype(bool)  # raises: cannot convert float NaN to bool\n\n// after\ns.fillna(False).astype(bool)","handlingStrategy":"validation","validationCode":"def safe_bool_cast(arr):\n    if getattr(arr, \"_hasna\", False):\n        raise ValueError(\"array has NA; fill or drop before casting to bool\")\n    return arr.astype(bool)","typeGuard":"def is_na_free(arr) -> bool:\n    return not getattr(arr, \"_hasna\", False)","tryCatchPattern":"try:\n    out = arr.astype(bool)\nexcept ValueError as e:\n    if \"cannot convert float NaN to bool\" in str(e):\n        out = arr.fillna(False).astype(bool)\n    else:\n        raise","preventionTips":["Fill or drop NAs before any bool cast.","Use to_numpy(dtype='bool', na_value=False) when a default is acceptable.","Keep boolean-mask construction behind a tested helper."],"tags":["masked-array","astype","missing-values","boolean"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}