Skip to content
14 changes: 13 additions & 1 deletion pandas/core/arrays/categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,9 @@ def astype(self, dtype: ExtensionDtype, copy: bool = ...) -> ExtensionArray: ...
@overload
def astype(self, dtype: AstypeArg, copy: bool = ...) -> ArrayLike: ...

def astype(self, dtype: AstypeArg, copy: bool = True) -> ArrayLike:
def astype(
self, dtype: AstypeArg, copy: bool = True, errors: str = "raise"
) -> ArrayLike:
"""
Coerce this type to another dtype

Expand All @@ -560,6 +562,11 @@ def astype(self, dtype: AstypeArg, copy: bool = True) -> ArrayLike:
By default, astype always returns a newly allocated object.
If copy is set to False and dtype is categorical, the original
object is returned.
errors : {'raise', 'ignore'}, default 'raise'
Control raising of exceptions on invalid data for provided dtype.

- 'raise' : allow exceptions to be raised
- 'ignore' : suppress exceptions. On error return original object
"""
dtype = pandas_dtype(dtype)
result: Categorical | np.ndarray
Expand Down Expand Up @@ -603,6 +610,11 @@ def astype(self, dtype: AstypeArg, copy: bool = True) -> ArrayLike:
msg = f"Cannot cast {self.categories.dtype} dtype to {dtype}"
raise ValueError(msg) from err

if errors == "raise" and not np.all(np.isin(self.codes, new_cats)):
raise ValueError(
"Cannot convert to CategoricalDtype with undefined values"
)

result = take_nd(
new_cats, ensure_platform_int(self._codes), fill_value=fill_value
)
Expand Down
Loading