Skip to content

Commit c78aa77

Browse files
committed
REF: avoid special-casing Categorical astype
1 parent 28cba66 commit c78aa77

File tree

4 files changed

+14
-19
lines changed

4 files changed

+14
-19
lines changed

pandas/core/arrays/integer.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from pandas.compat.numpy import function as nv
1010
from pandas.util._decorators import cache_readonly
1111

12-
from pandas.core.dtypes.base import register_extension_dtype
12+
from pandas.core.dtypes.base import ExtensionDtype, register_extension_dtype
1313
from pandas.core.dtypes.common import (
1414
is_bool_dtype,
1515
is_datetime64_dtype,
@@ -409,6 +409,11 @@ def astype(self, dtype, copy: bool = True) -> ArrayLike:
409409
elif isinstance(dtype, StringDtype):
410410
return dtype.construct_array_type()._from_sequence(self, copy=False)
411411

412+
elif isinstance(dtype, ExtensionDtype):
413+
# e.g. Categorical
414+
cls = dtype.construct_array_type()
415+
return cls._from_sequence(self, dtype=dtype, copy=copy)
416+
412417
# coerce
413418
if is_float_dtype(dtype):
414419
# In astype, we consider dtype=float to also mean na_value=np.nan

pandas/core/indexes/category.py

-5
Original file line numberDiff line numberDiff line change
@@ -375,11 +375,6 @@ def __contains__(self, key: Any) -> bool:
375375

376376
return contains(self, key, container=self._engine)
377377

378-
@doc(Index.astype)
379-
def astype(self, dtype, copy=True):
380-
res_data = self._data.astype(dtype, copy=copy)
381-
return Index(res_data, name=self.name)
382-
383378
@doc(Index.fillna)
384379
def fillna(self, value, downcast=None):
385380
value = self._require_scalar(value)

pandas/core/indexes/extension.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from pandas.errors import AbstractMethodError
1212
from pandas.util._decorators import cache_readonly, doc
1313

14-
from pandas.core.dtypes.common import is_dtype_equal, is_object_dtype
14+
from pandas.core.dtypes.common import is_dtype_equal, is_object_dtype, pandas_dtype
1515
from pandas.core.dtypes.generic import ABCDataFrame, ABCSeries
1616

1717
from pandas.core.arrays import ExtensionArray
@@ -294,9 +294,12 @@ def map(self, mapper, na_action=None):
294294

295295
@doc(Index.astype)
296296
def astype(self, dtype, copy=True):
297-
if is_dtype_equal(self.dtype, dtype) and copy is False:
298-
# Ensure that self.astype(self.dtype) is self
299-
return self
297+
dtype = pandas_dtype(dtype)
298+
if is_dtype_equal(self.dtype, dtype):
299+
if not copy:
300+
# Ensure that self.astype(self.dtype) is self
301+
return self
302+
return self.copy()
300303

301304
new_values = self._data.astype(dtype, copy=copy)
302305

pandas/core/internals/blocks.py

+1-9
Original file line numberDiff line numberDiff line change
@@ -642,15 +642,7 @@ def astype(self, dtype, copy: bool = False, errors: str = "raise"):
642642
def _astype(self, dtype: DtypeObj, copy: bool) -> ArrayLike:
643643
values = self.values
644644

645-
if is_categorical_dtype(dtype):
646-
647-
if is_categorical_dtype(values.dtype):
648-
# GH#10696/GH#18593: update an existing categorical efficiently
649-
return values.astype(dtype, copy=copy)
650-
651-
return Categorical(values, dtype=dtype)
652-
653-
elif is_datetime64tz_dtype(dtype) and is_datetime64_dtype(values.dtype):
645+
if is_datetime64tz_dtype(dtype) and is_datetime64_dtype(values.dtype):
654646
# if we are passed a datetime64[ns, tz]
655647
if copy:
656648
# this should be the only copy

0 commit comments

Comments
 (0)