Skip to content

Commit 2fb2fdb

Browse files
committed
BUG: Series(category).replace to maintain order of categories
1 parent 852518e commit 2fb2fdb

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

pandas/core/arrays/categorical.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -2284,7 +2284,13 @@ 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+
new_categories = ser.drop_duplicates(keep="first")
2288+
2289+
# GH51016: maintain order of existing categories
2290+
overlap = cat.categories[cat.categories.isin(new_categories)]
2291+
new_categories[new_categories.isin(overlap)] = overlap
2292+
2293+
new_categories = Index(new_categories)
22882294
new_codes = recode_for_categories(
22892295
cat._codes, all_values, new_categories, copy=False
22902296
)

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)