Skip to content

Commit 6478e70

Browse files
authored
BUG: Series(category).replace to maintain order of categories (#51057)
* BUG: Series(category).replace to maintain order of categories * fix
1 parent 80ecde4 commit 6478e70

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

pandas/core/arrays/categorical.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -2284,7 +2284,16 @@ def _replace(self, *, to_replace, value, inplace: bool = False):
22842284
ser = ser.replace(to_replace=to_replace, value=value)
22852285

22862286
all_values = Index(ser)
2287-
new_categories = Index(ser.drop_duplicates(keep="first"))
2287+
2288+
# GH51016: maintain order of existing categories
2289+
idxr = cat.categories.get_indexer_for(all_values)
2290+
locs = np.arange(len(ser))
2291+
locs = np.where(idxr == -1, locs, idxr)
2292+
locs = locs.argsort()
2293+
2294+
new_categories = ser.take(locs)
2295+
new_categories = new_categories.drop_duplicates(keep="first")
2296+
new_categories = Index(new_categories)
22882297
new_codes = recode_for_categories(
22892298
cat._codes, all_values, new_categories, copy=False
22902299
)

pandas/tests/arrays/categorical/test_replace.py

+10
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,13 @@ def test_replace_categorical_ea_dtype():
7878
result = pd.Series(cat).replace(["a", "b"], ["c", pd.NA])._values
7979
expected = Categorical(pd.array(["c", pd.NA], dtype="string"))
8080
tm.assert_categorical_equal(result, expected)
81+
82+
83+
def test_replace_maintain_ordering():
84+
# GH51016
85+
dtype = pd.CategoricalDtype([0, 1, 2], ordered=True)
86+
ser = pd.Series([0, 1, 2], dtype=dtype)
87+
result = ser.replace(0, 2)
88+
expected_dtype = pd.CategoricalDtype([1, 2], ordered=True)
89+
expected = pd.Series([2, 1, 2], dtype=expected_dtype)
90+
tm.assert_series_equal(expected, result, check_category_order=True)

0 commit comments

Comments
 (0)