@@ -673,6 +673,7 @@ def copy(self, deep: bool = True):
673673 # ---------------------------------------------------------------------
674674 # Replace
675675
676+ @final
676677 def replace (
677678 self ,
678679 to_replace ,
@@ -687,15 +688,30 @@ def replace(
687688 """
688689 inplace = validate_bool_kwarg (inplace , "inplace" )
689690
691+ # Note: the checks we do in NDFrame.replace ensure we never get
692+ # here with listlike to_replace or value, as those cases
693+ # go through _replace_list
694+
695+ values = self .values
696+
697+ if isinstance (values , Categorical ):
698+ # TODO: avoid special-casing
699+ blk = self if inplace else self .copy ()
700+ blk .values .replace (to_replace , value , inplace = True )
701+ return [blk ]
702+
703+ regex = should_use_regex (regex , to_replace )
704+
705+ if regex :
706+ return self ._replace_regex (to_replace , value , inplace = inplace )
707+
690708 if not self ._can_hold_element (to_replace ):
691709 # We cannot hold `to_replace`, so we know immediately that
692710 # replacing it is a no-op.
693711 # Note: If to_replace were a list, NDFrame.replace would call
694712 # replace_list instead of replace.
695713 return [self ] if inplace else [self .copy ()]
696714
697- values = self .values
698-
699715 mask = missing .mask_missing (values , to_replace )
700716 if not mask .any ():
701717 # Note: we get here with test_replace_extension_other incorrectly
@@ -720,7 +736,7 @@ def replace(
720736 else :
721737 # split so that we only upcast where necessary
722738 return self .split_and_operate (
723- type (self ).replace , to_replace , value , inplace = inplace , regex = regex
739+ type (self ).replace , to_replace , value , inplace = True , regex = regex
724740 )
725741
726742 @final
@@ -1223,7 +1239,7 @@ def take_nd(
12231239 Take values according to indexer and return them as a block.bb
12241240
12251241 """
1226- # algos.take_nd dispatches for DatetimeTZBlock, CategoricalBlock
1242+ # algos.take_nd dispatches for DatetimeTZBlock
12271243 # so need to preserve types
12281244 # sparse is treated like an ndarray, but needs .get_values() shaping
12291245
@@ -1422,7 +1438,7 @@ class ExtensionBlock(Block):
14221438 Notes
14231439 -----
14241440 This holds all 3rd-party extension array types. It's also the immediate
1425- parent class for our internal extension types' blocks, CategoricalBlock .
1441+ parent class for our internal extension types' blocks.
14261442
14271443 ExtensionArrays are limited to 1-D.
14281444 """
@@ -1579,7 +1595,6 @@ def take_nd(
15791595
15801596 def _can_hold_element (self , element : Any ) -> bool :
15811597 # TODO: We may need to think about pushing this onto the array.
1582- # We're doing the same as CategoricalBlock here.
15831598 return True
15841599
15851600 def _slice (self , slicer ):
@@ -2019,41 +2034,6 @@ def _maybe_downcast(self, blocks: List[Block], downcast=None) -> List[Block]:
20192034 def _can_hold_element (self , element : Any ) -> bool :
20202035 return True
20212036
2022- def replace (
2023- self ,
2024- to_replace ,
2025- value ,
2026- inplace : bool = False ,
2027- regex : bool = False ,
2028- ) -> List [Block ]:
2029- # Note: the checks we do in NDFrame.replace ensure we never get
2030- # here with listlike to_replace or value, as those cases
2031- # go through _replace_list
2032-
2033- regex = should_use_regex (regex , to_replace )
2034-
2035- if regex :
2036- return self ._replace_regex (to_replace , value , inplace = inplace )
2037- else :
2038- return super ().replace (to_replace , value , inplace = inplace , regex = False )
2039-
2040-
2041- class CategoricalBlock (ExtensionBlock ):
2042- __slots__ = ()
2043-
2044- def replace (
2045- self ,
2046- to_replace ,
2047- value ,
2048- inplace : bool = False ,
2049- regex : bool = False ,
2050- ) -> List [Block ]:
2051- inplace = validate_bool_kwarg (inplace , "inplace" )
2052- result = self if inplace else self .copy ()
2053-
2054- result .values .replace (to_replace , value , inplace = True )
2055- return [result ]
2056-
20572037
20582038# -----------------------------------------------------------------
20592039# Constructor Helpers
@@ -2116,7 +2096,7 @@ def get_block_type(values, dtype: Optional[Dtype] = None):
21162096 # Need this first(ish) so that Sparse[datetime] is sparse
21172097 cls = ExtensionBlock
21182098 elif isinstance (dtype , CategoricalDtype ):
2119- cls = CategoricalBlock
2099+ cls = ExtensionBlock
21202100 elif vtype is Timestamp :
21212101 cls = DatetimeTZBlock
21222102 elif vtype is Interval or vtype is Period :
0 commit comments