{"record":{"id":"cf37c4a1c9256b6b","repo":"pandas-dev/pandas","slug":"cannot-safely-cast-non-equivalent-values-dtype-t","errorCode":null,"errorMessage":"cannot safely cast non-equivalent {values.dtype} to {np.dtype(dtype)}","messagePattern":"cannot safely cast non-equivalent (.+?) to (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/integer.py","lineNumber":69,"sourceCode":"    def _get_dtype_mapping(cls) -> dict[np.dtype, IntegerDtype]:\n        return NUMPY_INT_TO_DTYPE\n\n    @classmethod\n    def _safe_cast(cls, values: np.ndarray, dtype: np.dtype, copy: bool) -> np.ndarray:\n        \"\"\"\n        Safely cast the values to the given dtype.\n\n        \"safe\" in this context means the casting is lossless. e.g. if 'values'\n        has a floating dtype, each value must be an integer.\n        \"\"\"\n        try:\n            return values.astype(dtype, casting=\"safe\", copy=copy)\n        except TypeError as err:\n            casted = values.astype(dtype, copy=copy)\n            if (casted == values).all():\n                return casted\n\n            raise TypeError(\n                f\"cannot safely cast non-equivalent {values.dtype} to {np.dtype(dtype)}\"\n            ) from err\n\n\n@set_module(\"pandas.arrays\")\nclass IntegerArray(NumericArray):\n    \"\"\"\n    Array of integer (optional missing) values.\n\n    Uses :attr:`pandas.NA` as the missing value.\n\n    .. warning::\n\n       IntegerArray is currently experimental, and its API or internal\n       implementation may change without warning.\n\n    We represent an IntegerArray with 2 numpy arrays:\n","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/integer.py#L51-L87","documentation":"Raised by IntegerArray._safe_cast when converting values to an integer dtype cannot be done losslessly (e.g. floats with fractional parts cast to int). 'safe' numpy casting failed and a follow-up equality check found data loss, so pandas refuses rather than silently truncate. TypeError naming both dtypes.","triggerScenarios":"Constructing a nullable IntegerArray ('Int64') from float data with non-integer values; astype('Int64') on a Series like [1.5, 2.0]; providing floats to a constructor expecting integer extension dtype.","commonSituations":"CSV/JSON parsed as float then cast to Int64 without rounding; mixing units where some rows are fractional; assuming integer-valued floats round-trip to Int64.","solutions":["Round or floor first if truncation is intended: s.round().astype('Int64').","Use a nullable float dtype ('Float64') if fractional values are legitimate.","Clean the data so every value is integral before casting."],"exampleFix":"# before\npd.Series([1.5, 2.0]).astype('Int64')\n# after\npd.Series([1.5, 2.0]).round().astype('Int64')","handlingStrategy":"validation","validationCode":"def to_int_nullable(s):\n    if pd.api.types.is_float_dtype(s) and not (s.dropna() % 1 == 0).all():\n        raise TypeError('float values are not integral; round or use Float64')\n    return s.astype('Int64')","typeGuard":"def is_integral_float(s) -> bool:\n    return pd.api.types.is_float_dtype(s) and bool((s.dropna() % 1 == 0).all())","tryCatchPattern":null,"preventionTips":["Round/floor before casting floats to Int64.","Use Float64 for genuine fractional data.","Validate integrality before nullable int casting."],"tags":["integer","nullable","dtype","casting","pandas"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}