@@ -673,6 +673,7 @@ def copy(self, deep: bool = True):
673
673
# ---------------------------------------------------------------------
674
674
# Replace
675
675
676
+ @final
676
677
def replace (
677
678
self ,
678
679
to_replace ,
@@ -687,15 +688,30 @@ def replace(
687
688
"""
688
689
inplace = validate_bool_kwarg (inplace , "inplace" )
689
690
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
+
690
708
if not self ._can_hold_element (to_replace ):
691
709
# We cannot hold `to_replace`, so we know immediately that
692
710
# replacing it is a no-op.
693
711
# Note: If to_replace were a list, NDFrame.replace would call
694
712
# replace_list instead of replace.
695
713
return [self ] if inplace else [self .copy ()]
696
714
697
- values = self .values
698
-
699
715
mask = missing .mask_missing (values , to_replace )
700
716
if not mask .any ():
701
717
# Note: we get here with test_replace_extension_other incorrectly
@@ -720,7 +736,7 @@ def replace(
720
736
else :
721
737
# split so that we only upcast where necessary
722
738
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
724
740
)
725
741
726
742
@final
@@ -1223,7 +1239,7 @@ def take_nd(
1223
1239
Take values according to indexer and return them as a block.bb
1224
1240
1225
1241
"""
1226
- # algos.take_nd dispatches for DatetimeTZBlock, CategoricalBlock
1242
+ # algos.take_nd dispatches for DatetimeTZBlock
1227
1243
# so need to preserve types
1228
1244
# sparse is treated like an ndarray, but needs .get_values() shaping
1229
1245
@@ -1422,7 +1438,7 @@ class ExtensionBlock(Block):
1422
1438
Notes
1423
1439
-----
1424
1440
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.
1426
1442
1427
1443
ExtensionArrays are limited to 1-D.
1428
1444
"""
@@ -1579,7 +1595,6 @@ def take_nd(
1579
1595
1580
1596
def _can_hold_element (self , element : Any ) -> bool :
1581
1597
# TODO: We may need to think about pushing this onto the array.
1582
- # We're doing the same as CategoricalBlock here.
1583
1598
return True
1584
1599
1585
1600
def _slice (self , slicer ):
@@ -2019,41 +2034,6 @@ def _maybe_downcast(self, blocks: List[Block], downcast=None) -> List[Block]:
2019
2034
def _can_hold_element (self , element : Any ) -> bool :
2020
2035
return True
2021
2036
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
-
2057
2037
2058
2038
# -----------------------------------------------------------------
2059
2039
# Constructor Helpers
@@ -2116,7 +2096,7 @@ def get_block_type(values, dtype: Optional[Dtype] = None):
2116
2096
# Need this first(ish) so that Sparse[datetime] is sparse
2117
2097
cls = ExtensionBlock
2118
2098
elif isinstance (dtype , CategoricalDtype ):
2119
- cls = CategoricalBlock
2099
+ cls = ExtensionBlock
2120
2100
elif vtype is Timestamp :
2121
2101
cls = DatetimeTZBlock
2122
2102
elif vtype is Interval or vtype is Period :
0 commit comments