@@ -373,7 +373,7 @@ def __init__(
373
373
# infer categories in a factorization step further below
374
374
375
375
if fastpath :
376
- self ._codes = coerce_indexer_dtype (values , dtype .categories )
376
+ self ._ndarray = coerce_indexer_dtype (values , dtype .categories )
377
377
self ._dtype = self ._dtype .update_dtype (dtype )
378
378
return
379
379
@@ -450,7 +450,7 @@ def __init__(
450
450
codes = full_codes
451
451
452
452
self ._dtype = self ._dtype .update_dtype (dtype )
453
- self ._codes = coerce_indexer_dtype (codes , dtype .categories )
453
+ self ._ndarray = coerce_indexer_dtype (codes , dtype .categories )
454
454
455
455
@property
456
456
def dtype (self ) -> CategoricalDtype :
@@ -923,7 +923,7 @@ def set_categories(self, new_categories, ordered=None, rename=False, inplace=Fal
923
923
codes = recode_for_categories (
924
924
cat .codes , cat .categories , new_dtype .categories
925
925
)
926
- cat ._codes = codes
926
+ cat ._ndarray = codes
927
927
cat ._dtype = new_dtype
928
928
929
929
if not inplace :
@@ -1096,7 +1096,7 @@ def add_categories(self, new_categories, inplace=False):
1096
1096
1097
1097
cat = self if inplace else self .copy ()
1098
1098
cat ._dtype = new_dtype
1099
- cat ._codes = coerce_indexer_dtype (cat ._codes , new_dtype .categories )
1099
+ cat ._ndarray = coerce_indexer_dtype (cat ._ndarray , new_dtype .categories )
1100
1100
if not inplace :
1101
1101
return cat
1102
1102
@@ -1201,7 +1201,7 @@ def remove_unused_categories(self, inplace=no_default):
1201
1201
new_categories , ordered = self .ordered
1202
1202
)
1203
1203
cat ._dtype = new_dtype
1204
- cat ._codes = coerce_indexer_dtype (inv , new_dtype .categories )
1204
+ cat ._ndarray = coerce_indexer_dtype (inv , new_dtype .categories )
1205
1205
1206
1206
if not inplace :
1207
1207
return cat
@@ -1384,6 +1384,10 @@ def __setstate__(self, state):
1384
1384
if "_dtype" not in state :
1385
1385
state ["_dtype" ] = CategoricalDtype (state ["_categories" ], state ["_ordered" ])
1386
1386
1387
+ if "_codes" in state and "_ndarray" not in state :
1388
+ # backward compat, changed what is property vs attribute
1389
+ state ["_ndarray" ] = state .pop ("_codes" )
1390
+
1387
1391
for k , v in state .items ():
1388
1392
setattr (self , k , v )
1389
1393
@@ -1785,11 +1789,11 @@ def fillna(self, value=None, method=None, limit=None):
1785
1789
# NDArrayBackedExtensionArray compat
1786
1790
1787
1791
@property
1788
- def _ndarray (self ) -> np .ndarray :
1789
- return self ._codes
1792
+ def _codes (self ) -> np .ndarray :
1793
+ return self ._ndarray
1790
1794
1791
1795
def _from_backing_data (self , arr : np .ndarray ) -> Categorical :
1792
- return self . _constructor (arr , dtype = self .dtype , fastpath = True )
1796
+ return type ( self ) (arr , dtype = self .dtype , fastpath = True )
1793
1797
1794
1798
def _box_func (self , i : int ):
1795
1799
if i == - 1 :
@@ -1800,7 +1804,7 @@ def _unbox_scalar(self, key) -> int:
1800
1804
# searchsorted is very performance sensitive. By converting codes
1801
1805
# to same dtype as self.codes, we get much faster performance.
1802
1806
code = self .categories .get_loc (key )
1803
- code = self ._codes .dtype .type (code )
1807
+ code = self ._ndarray .dtype .type (code )
1804
1808
return code
1805
1809
1806
1810
# ------------------------------------------------------------------
@@ -2162,7 +2166,7 @@ def unique(self):
2162
2166
cat = self .copy ()
2163
2167
2164
2168
# keep nan in codes
2165
- cat ._codes = unique_codes
2169
+ cat ._ndarray = unique_codes
2166
2170
2167
2171
# exclude nan from indexer for categories
2168
2172
take_codes = unique_codes [unique_codes != - 1 ]
0 commit comments