pandas-dev/pandas · error · TypeError
Cannot round dtype {self.dtype} as it is non-numeric
Error message
Cannot round dtype {self.dtype} as it is non-numeric What it means
ExtensionArray.round (base.py:2945) rejects dtypes that are neither boolean (returned as-is) nor numeric; it raises TypeError. Rounding only makes sense for numeric data, so non-numeric EAs (string, object, datetime) are refused.
Source
Thrown at pandas/core/arrays/base.py:2945
Series.round : Round values of a Series.
Notes
-----
This is a non-performant default implementation. Subclasses are
encouraged to override it to avoid the elementwise loop.
Examples
--------
>>> arr = pd.array([1.234, 5.678, pd.NA], dtype="Float64")
>>> arr.round(1)
<FloatingArray>
[1.2, 5.7, <NA>]
Length: 3, dtype: Float64
"""
if self.dtype._is_boolean:
return self.copy()
if not self.dtype._is_numeric:
raise TypeError(f"Cannot round dtype {self.dtype} as it is non-numeric")
# Python's builtin round on complex emits DeprecationWarning (and
# raises TypeError in a future Python release); use np.round there.
round_fn = np.round if self.dtype.kind == "c" else round
rounded = [
round_fn(item, decimals) if not item_isna else item
for item, item_isna in zip(self, self.isna(), strict=True)
]
return type(self)._from_sequence(rounded, dtype=self.dtype)
def __array_ufunc__(self, ufunc: np.ufunc, method: str, *inputs, **kwargs):
if any(
isinstance(other, (ABCSeries, ABCIndex, ABCDataFrame)) for other in inputs
):
return NotImplemented
result = arraylike.maybe_dispatch_ufunc_to_dunder_op(
self, ufunc, method, *inputs, **kwargs
)View on GitHub (pinned to 71959b8cb9)
Solutions
- Apply round only to numeric columns: df.select_dtypes(include='number').round().
- Convert the column to numeric first: s.astype('Float64').round().
- If your custom EA is numeric, ensure its dtype._is_numeric returns True.
- Drop or exclude non-numeric columns from the round() call.
Example fix
# before df.round() # raises if df has a 'string' column # after df_num = df.select_dtypes(include="number") df[df_num.columns] = df_num.round()
Defensive patterns
Strategy: validation
Validate before calling
def safe_round(s, decimals=0):
import pandas as pd
if not pd.api.types.is_numeric_dtype(s):
return s
return s.round(decimals) Type guard
def is_roundable(dtype) -> bool:
import pandas as pd
return pd.api.types.is_numeric_dtype(dtype) or pd.api.types.is_bool_dtype(dtype) Try / catch
try:
df.round()
except TypeError as e:
if "non-numeric" in str(e):
num = df.select_dtypes("number")
df[num.columns] = num.round()
else:
raise Prevention
- Round only numeric columns
- Use select_dtypes(include='number')
- Mark custom numeric EAs via dtype._is_numeric
When it happens
Trigger: Calling s.round() or df.round() on a Series/column whose EA dtype._is_numeric is False and _is_boolean is False (e.g. string, categorical-of-strings, some custom EA).
Common situations: Running df.round() on a mixed DataFrame that includes string or datetime columns; calling round on a custom EA that did not mark itself numeric; data ingestion that left numeric-looking data as strings.
Related errors
- '{type(self).__name__}' with dtype {self.dtype} does not sup
- bins argument only works with numeric data.
- cannot diff {type(arr).__name__} on axis={axis}
- {type(arr).__name__} has no 'diff' method. Convert to a suit
- Column {colname} must have a numeric dtype. Found '{dtype}'
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/3422698b39db0d85.
Report an issue: GitHub.