{"record":{"id":"2958cb277e2ce7d2","repo":"pandas-dev/pandas","slug":"cannot-convert-float-nan-to-integer","errorCode":null,"errorMessage":"Cannot convert float NaN to integer","messagePattern":"Cannot convert float NaN to integer","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/categorical.py","lineNumber":623,"sourceCode":"            # GH 10696/18593/18630\n            dtype = self.dtype.update_dtype(dtype)\n            self = self.copy() if copy else self\n            result = self._set_dtype(dtype, copy=False)\n            wrong = result.isna() & ~self.isna()\n            if wrong.any():\n                warnings.warn(\n                    \"Constructing a Categorical with a dtype and values containing \"\n                    \"non-null entries not in that dtype's categories is deprecated \"\n                    \"and will raise in a future version.\",\n                    Pandas4Warning,\n                    stacklevel=find_stack_level(),\n                )\n\n        elif isinstance(dtype, ExtensionDtype):\n            return super().astype(dtype, copy=copy)\n\n        elif dtype.kind in \"iu\" and self.isna().any():\n            raise ValueError(\"Cannot convert float NaN to integer\")\n\n        elif len(self.codes) == 0 or len(self.categories) == 0:\n            # For NumPy 1.x compatibility we cannot use copy=None.  And\n            # `copy=False` has the meaning of `copy=None` here:\n            if not copy:\n                result = np.asarray(self, dtype=dtype)\n            else:\n                result = np.array(self, dtype=dtype)\n\n        else:\n            # GH8628 (PERF): astype category codes instead of astyping array\n            new_cats = self.categories._values\n\n            try:\n                new_cats = new_cats.astype(dtype=dtype, copy=copy)\n                fill_value = self.categories._na_value\n                if not is_valid_na_for_dtype(fill_value, dtype):\n                    fill_value = lib.item_from_zerodim(","sourceCodeStart":605,"sourceCodeEnd":641,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/categorical.py#L605-L641","documentation":"Raised by Categorical.astype when casting to an integer dtype ('i' or 'u' kind) while the categorical contains missing values (NaN, coded internally as -1). Integers cannot represent NaN, so pandas refuses rather than silently coercing to a sentinel.","triggerScenarios":"`cat.astype('int')`, `cat.astype(np.int64)`, or `cat.astype('Int64')`-via-int path when `cat.isna().any()` is True. Commonly hit when a categorical came from data with missing entries.","commonSituations":"Reading survey/enum data with blanks, then converting codes to int for modeling; or downstream code assuming no missing values.","solutions":["Fill missing values first: `cat.fillna(...).astype('int')` or use a sentinel category.","Cast to pandas' nullable integer: `cat.astype('Int64')` (Int64 accepts pd.NA).","Drop NaN rows: `cat.dropna().astype('int')` if appropriate.","Operate on codes directly via `cat.codes` (already int, with -1 for missing)."],"exampleFix":"# before\ncat = pd.Categorical(['a', None, 'b'])\ncat.astype(int)\n# after\ncat = pd.Categorical(['a', None, 'b'])\ncat.astype('Int64')  # nullable integer, then map if needed","handlingStrategy":"validation","validationCode":"def cat_to_int(cat):\n    if cat.isna().any():\n        return cat.astype('Int64')  # nullable int\n    return cat.astype('int64')","typeGuard":"def has_no_na(cat) -> bool:\n    return not bool(cat.isna().any())","tryCatchPattern":"try:\n    out = cat.astype('int')\nexcept ValueError as e:\n    if 'NaN to integer' in str(e):\n        out = cat.astype('Int64')\n    else:\n        raise","preventionTips":["Use nullable 'Int64' when missing values are possible.","Drop or fill NA before astype to plain int.","Use cat.codes (int, -1 for NA) when you want positions."],"tags":["categorical","astype","nan","integer","valueerror"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}