Skip to content

Commit e38e987

Browse files
authored
REF: re-use validate_setitem_value in Categorical.fillna (#37597)
1 parent a5aed5d commit e38e987

File tree

5 files changed

+14
-17
lines changed

5 files changed

+14
-17
lines changed

Diff for: pandas/core/arrays/categorical.py

+4-10
Original file line numberDiff line numberDiff line change
@@ -1655,21 +1655,15 @@ def fillna(self, value=None, method=None, limit=None):
16551655
codes = self._ndarray.copy()
16561656
mask = self.isna()
16571657

1658+
new_codes = self._validate_setitem_value(value)
1659+
16581660
if isinstance(value, (np.ndarray, Categorical)):
16591661
# We get ndarray or Categorical if called via Series.fillna,
16601662
# where it will unwrap another aligned Series before getting here
1661-
1662-
not_categories = ~algorithms.isin(value, self.categories)
1663-
if not isna(value[not_categories]).all():
1664-
# All entries in `value` must either be a category or NA
1665-
raise ValueError("fill value must be in categories")
1666-
1667-
values_codes = _get_codes_for_values(value, self.categories)
1668-
codes[mask] = values_codes[mask]
1663+
codes[mask] = new_codes[mask]
16691664

16701665
else:
1671-
new_code = self._validate_fill_value(value)
1672-
codes[mask] = new_code
1666+
codes[mask] = new_codes
16731667

16741668
return self._from_backing_data(codes)
16751669

Diff for: pandas/tests/arrays/categorical/test_missing.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ def test_set_item_nan(self):
6060
),
6161
(dict(), "Must specify a fill 'value' or 'method'."),
6262
(dict(method="bad"), "Invalid fill method. Expecting .* bad"),
63-
(dict(value=Series([1, 2, 3, 4, "a"])), "fill value must be in categories"),
63+
(
64+
dict(value=Series([1, 2, 3, 4, "a"])),
65+
"Cannot setitem on a Categorical with a new category",
66+
),
6467
],
6568
)
6669
def test_fillna_raises(self, fillna_kwargs, msg):

Diff for: pandas/tests/frame/methods/test_fillna.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def test_na_actions_categorical(self):
170170
res = df.fillna(value={"cats": 3, "vals": "b"})
171171
tm.assert_frame_equal(res, df_exp_fill)
172172

173-
msg = "'fill_value=4' is not present in this Categorical's categories"
173+
msg = "Cannot setitem on a Categorical with a new category"
174174
with pytest.raises(ValueError, match=msg):
175175
df.fillna(value={"cats": 4, "vals": "c"})
176176

Diff for: pandas/tests/indexes/categorical/test_fillna.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def test_fillna_categorical(self):
1414
tm.assert_index_equal(idx.fillna(1.0), exp)
1515

1616
# fill by value not in categories raises ValueError
17-
msg = "'fill_value=2.0' is not present in this Categorical's categories"
17+
msg = "Cannot setitem on a Categorical with a new category"
1818
with pytest.raises(ValueError, match=msg):
1919
idx.fillna(2.0)
2020

@@ -36,7 +36,7 @@ def test_fillna_validates_with_no_nas(self):
3636
ci = CategoricalIndex([2, 3, 3])
3737
cat = ci._data
3838

39-
msg = "'fill_value=False' is not present in this Categorical's categories"
39+
msg = "Cannot setitem on a Categorical with a new category"
4040
with pytest.raises(ValueError, match=msg):
4141
ci.fillna(False)
4242

Diff for: pandas/tests/series/methods/test_fillna.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -653,14 +653,14 @@ def test_fillna_categorical_raises(self):
653653
data = ["a", np.nan, "b", np.nan, np.nan]
654654
ser = Series(Categorical(data, categories=["a", "b"]))
655655

656-
msg = "'fill_value=d' is not present in this Categorical's categories"
656+
msg = "Cannot setitem on a Categorical with a new category"
657657
with pytest.raises(ValueError, match=msg):
658658
ser.fillna("d")
659659

660-
with pytest.raises(ValueError, match="fill value must be in categories"):
660+
with pytest.raises(ValueError, match=msg):
661661
ser.fillna(Series("d"))
662662

663-
with pytest.raises(ValueError, match="fill value must be in categories"):
663+
with pytest.raises(ValueError, match=msg):
664664
ser.fillna({1: "d", 3: "a"})
665665

666666
msg = '"value" parameter must be a scalar or dict, but you passed a "list"'

0 commit comments

Comments
 (0)