pandas-dev/pandas · error · TypeError
cannot safely cast non-equivalent {values.dtype} to {np.dtyp
Error message
cannot safely cast non-equivalent {values.dtype} to {np.dtype(dtype)} What it means
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.
Source
Thrown at pandas/core/arrays/integer.py:69
def _get_dtype_mapping(cls) -> dict[np.dtype, IntegerDtype]:
return NUMPY_INT_TO_DTYPE
@classmethod
def _safe_cast(cls, values: np.ndarray, dtype: np.dtype, copy: bool) -> np.ndarray:
"""
Safely cast the values to the given dtype.
"safe" in this context means the casting is lossless. e.g. if 'values'
has a floating dtype, each value must be an integer.
"""
try:
return values.astype(dtype, casting="safe", copy=copy)
except TypeError as err:
casted = values.astype(dtype, copy=copy)
if (casted == values).all():
return casted
raise TypeError(
f"cannot safely cast non-equivalent {values.dtype} to {np.dtype(dtype)}"
) from err
@set_module("pandas.arrays")
class IntegerArray(NumericArray):
"""
Array of integer (optional missing) values.
Uses :attr:`pandas.NA` as the missing value.
.. warning::
IntegerArray is currently experimental, and its API or internal
implementation may change without warning.
We represent an IntegerArray with 2 numpy arrays:
View on GitHub (pinned to 71959b8cb9)
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.
Example fix
# before
pd.Series([1.5, 2.0]).astype('Int64')
# after
pd.Series([1.5, 2.0]).round().astype('Int64') Defensive patterns
Strategy: validation
Validate before calling
def to_int_nullable(s):
if pd.api.types.is_float_dtype(s) and not (s.dropna() % 1 == 0).all():
raise TypeError('float values are not integral; round or use Float64')
return s.astype('Int64') Type guard
def is_integral_float(s) -> bool:
return pd.api.types.is_float_dtype(s) and bool((s.dropna() % 1 == 0).all()) Prevention
- Round/floor before casting floats to Int64.
- Use Float64 for genuine fractional data.
- Validate integrality before nullable int casting.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Column {colname} must have a numeric dtype. Found '{dtype}'
- Column {colname} is backed by an extension array, which is n
- No masked accumulation defined for dtype {values.dtype.type}
- dtype {data.dtype} cannot be converted to datetime64[ns]
- Passing PeriodDtype data is invalid. Use `data.to_timestamp(
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/cf37c4a1c9256b6b.
Report an issue: GitHub.