Skip to content

Commit 9cf9a12

Browse files
jbrockmendelluckyvs1
authored andcommitted
BUG: disallow scalar in Categorical constructor (pandas-dev#38472)
1 parent 81761f1 commit 9cf9a12

File tree

6 files changed

+25
-9
lines changed

6 files changed

+25
-9
lines changed

doc/source/whatsnew/v1.3.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ Other API changes
144144

145145
Deprecations
146146
~~~~~~~~~~~~
147+
- Deprecating allowing scalars passed to the :class:`Categorical` constructor (:issue:`38433`)
147148
- Deprecated allowing subclass-specific keyword arguments in the :class:`Index` constructor, use the specific subclass directly instead (:issue:`14093`,:issue:`21311`,:issue:`22315`,:issue:`26974`)
148149
-
149150
-

pandas/core/arrays/categorical.py

+10
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,16 @@ def __init__(
320320
self._dtype = self._dtype.update_dtype(dtype)
321321
return
322322

323+
if not is_list_like(values):
324+
# GH#38433
325+
warn(
326+
"Allowing scalars in the Categorical constructor is deprecated "
327+
"and will raise in a future version. Use `[value]` instead",
328+
FutureWarning,
329+
stacklevel=2,
330+
)
331+
values = [values]
332+
323333
# null_mask indicates missing values we want to exclude from inference.
324334
# This means: only missing values in list-likes (not arrays/ndframes).
325335
null_mask = np.array(False)

pandas/tests/arrays/categorical/test_constructors.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626

2727

2828
class TestCategoricalConstructors:
29+
def test_categorical_scalar_deprecated(self):
30+
# GH#38433
31+
with tm.assert_produces_warning(FutureWarning):
32+
Categorical("A", categories=["A", "B"])
33+
2934
def test_validate_ordered(self):
3035
# see gh-14058
3136
exp_msg = "'ordered' must either be 'True' or 'False'"
@@ -202,13 +207,13 @@ def test_constructor(self):
202207
assert len(cat.codes) == 1
203208
assert cat.codes[0] == 0
204209

205-
# Scalars should be converted to lists
206-
cat = Categorical(1)
210+
with tm.assert_produces_warning(FutureWarning):
211+
# GH#38433
212+
cat = Categorical(1)
207213
assert len(cat.categories) == 1
208214
assert cat.categories[0] == 1
209215
assert len(cat.codes) == 1
210216
assert cat.codes[0] == 0
211-
212217
# two arrays
213218
# - when the first is an integer dtype and the second is not
214219
# - when the resulting codes are all -1/NaN

pandas/tests/extension/test_categorical.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ def test_cast_category_to_extension_dtype(self, expected):
223223
)
224224
def test_consistent_casting(self, dtype, expected):
225225
# GH 28448
226-
result = Categorical("2015-01-01").astype(dtype)
226+
result = Categorical(["2015-01-01"]).astype(dtype)
227227
assert result == expected
228228

229229

pandas/tests/series/methods/test_replace.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ def test_replace_mixed_types_with_string(self):
290290
@pytest.mark.parametrize(
291291
"categorical, numeric",
292292
[
293-
(pd.Categorical("A", categories=["A", "B"]), [1]),
293+
(pd.Categorical(["A"], categories=["A", "B"]), [1]),
294294
(pd.Categorical(("A",), categories=["A", "B"]), [1]),
295295
(pd.Categorical(("A", "B"), categories=["A", "B"]), [1, 2]),
296296
],

pandas/tests/test_algos.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -908,17 +908,17 @@ def test_categorical_from_codes(self):
908908
# GH 16639
909909
vals = np.array([0, 1, 2, 0])
910910
cats = ["a", "b", "c"]
911-
Sd = Series(Categorical(1).from_codes(vals, cats))
912-
St = Series(Categorical(1).from_codes(np.array([0, 1]), cats))
911+
Sd = Series(Categorical([1]).from_codes(vals, cats))
912+
St = Series(Categorical([1]).from_codes(np.array([0, 1]), cats))
913913
expected = np.array([True, True, False, True])
914914
result = algos.isin(Sd, St)
915915
tm.assert_numpy_array_equal(expected, result)
916916

917917
def test_categorical_isin(self):
918918
vals = np.array([0, 1, 2, 0])
919919
cats = ["a", "b", "c"]
920-
cat = Categorical(1).from_codes(vals, cats)
921-
other = Categorical(1).from_codes(np.array([0, 1]), cats)
920+
cat = Categorical([1]).from_codes(vals, cats)
921+
other = Categorical([1]).from_codes(np.array([0, 1]), cats)
922922

923923
expected = np.array([True, True, False, True])
924924
result = algos.isin(cat, other)

0 commit comments

Comments
 (0)