Skip to content

Commit 2eca9e8

Browse files
authored
CLN/REF: Split up / clean Categorical constructor tests (#32211)
* Split / parametrize * Dedupe some code * Parametrize * Add back from_codes for empty * Add comment
1 parent 2227c83 commit 2eca9e8

File tree

1 file changed

+36
-37
lines changed

1 file changed

+36
-37
lines changed

pandas/tests/arrays/categorical/test_constructors.py

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,9 @@ def test_constructor_from_index_series_period(self):
353353
result = Categorical(Series(idx))
354354
tm.assert_index_equal(result.categories, idx)
355355

356-
def test_constructor_invariant(self):
357-
# GH 14190
358-
vals = [
356+
@pytest.mark.parametrize(
357+
"values",
358+
[
359359
np.array([1.0, 1.2, 1.8, np.nan]),
360360
np.array([1, 2, 3], dtype="int64"),
361361
["a", "b", "c", np.nan],
@@ -366,11 +366,13 @@ def test_constructor_invariant(self):
366366
Timestamp("2014-01-02", tz="US/Eastern"),
367367
NaT,
368368
],
369-
]
370-
for val in vals:
371-
c = Categorical(val)
372-
c2 = Categorical(c)
373-
tm.assert_categorical_equal(c, c2)
369+
],
370+
)
371+
def test_constructor_invariant(self, values):
372+
# GH 14190
373+
c = Categorical(values)
374+
c2 = Categorical(c)
375+
tm.assert_categorical_equal(c, c2)
374376

375377
@pytest.mark.parametrize("ordered", [True, False])
376378
def test_constructor_with_dtype(self, ordered):
@@ -470,61 +472,66 @@ def test_construction_with_null(self, klass, nulls_fixture):
470472

471473
tm.assert_categorical_equal(result, expected)
472474

473-
def test_from_codes(self):
475+
def test_from_codes_empty(self):
476+
cat = ["a", "b", "c"]
477+
result = Categorical.from_codes([], categories=cat)
478+
expected = Categorical([], categories=cat)
474479

475-
# too few categories
480+
tm.assert_categorical_equal(result, expected)
481+
482+
def test_from_codes_too_few_categories(self):
476483
dtype = CategoricalDtype(categories=[1, 2])
477484
msg = "codes need to be between "
478485
with pytest.raises(ValueError, match=msg):
479486
Categorical.from_codes([1, 2], categories=dtype.categories)
480487
with pytest.raises(ValueError, match=msg):
481488
Categorical.from_codes([1, 2], dtype=dtype)
482489

483-
# no int codes
490+
def test_from_codes_non_int_codes(self):
491+
dtype = CategoricalDtype(categories=[1, 2])
484492
msg = "codes need to be array-like integers"
485493
with pytest.raises(ValueError, match=msg):
486494
Categorical.from_codes(["a"], categories=dtype.categories)
487495
with pytest.raises(ValueError, match=msg):
488496
Categorical.from_codes(["a"], dtype=dtype)
489497

490-
# no unique categories
498+
def test_from_codes_non_unique_categories(self):
491499
with pytest.raises(ValueError, match="Categorical categories must be unique"):
492500
Categorical.from_codes([0, 1, 2], categories=["a", "a", "b"])
493501

494-
# NaN categories included
502+
def test_from_codes_nan_cat_included(self):
495503
with pytest.raises(ValueError, match="Categorial categories cannot be null"):
496504
Categorical.from_codes([0, 1, 2], categories=["a", "b", np.nan])
497505

498-
# too negative
506+
def test_from_codes_too_negative(self):
499507
dtype = CategoricalDtype(categories=["a", "b", "c"])
500508
msg = r"codes need to be between -1 and len\(categories\)-1"
501509
with pytest.raises(ValueError, match=msg):
502510
Categorical.from_codes([-2, 1, 2], categories=dtype.categories)
503511
with pytest.raises(ValueError, match=msg):
504512
Categorical.from_codes([-2, 1, 2], dtype=dtype)
505513

514+
def test_from_codes(self):
515+
dtype = CategoricalDtype(categories=["a", "b", "c"])
506516
exp = Categorical(["a", "b", "c"], ordered=False)
507517
res = Categorical.from_codes([0, 1, 2], categories=dtype.categories)
508518
tm.assert_categorical_equal(exp, res)
509519

510520
res = Categorical.from_codes([0, 1, 2], dtype=dtype)
511521
tm.assert_categorical_equal(exp, res)
512522

513-
def test_from_codes_with_categorical_categories(self):
523+
@pytest.mark.parametrize("klass", [Categorical, CategoricalIndex])
524+
def test_from_codes_with_categorical_categories(self, klass):
514525
# GH17884
515526
expected = Categorical(["a", "b"], categories=["a", "b", "c"])
516527

517-
result = Categorical.from_codes([0, 1], categories=Categorical(["a", "b", "c"]))
528+
result = Categorical.from_codes([0, 1], categories=klass(["a", "b", "c"]))
518529
tm.assert_categorical_equal(result, expected)
519530

520-
result = Categorical.from_codes(
521-
[0, 1], categories=CategoricalIndex(["a", "b", "c"])
522-
)
523-
tm.assert_categorical_equal(result, expected)
524-
525-
# non-unique Categorical still raises
531+
@pytest.mark.parametrize("klass", [Categorical, CategoricalIndex])
532+
def test_from_codes_with_non_unique_categorical_categories(self, klass):
526533
with pytest.raises(ValueError, match="Categorical categories must be unique"):
527-
Categorical.from_codes([0, 1], Categorical(["a", "b", "a"]))
534+
Categorical.from_codes([0, 1], klass(["a", "b", "a"]))
528535

529536
def test_from_codes_with_nan_code(self):
530537
# GH21767
@@ -535,24 +542,16 @@ def test_from_codes_with_nan_code(self):
535542
with pytest.raises(ValueError, match="codes need to be array-like integers"):
536543
Categorical.from_codes(codes, dtype=dtype)
537544

538-
def test_from_codes_with_float(self):
545+
@pytest.mark.parametrize("codes", [[1.0, 2.0, 0], [1.1, 2.0, 0]])
546+
def test_from_codes_with_float(self, codes):
539547
# GH21767
540-
codes = [1.0, 2.0, 0] # integer, but in float dtype
548+
# float codes should raise even if values are equal to integers
541549
dtype = CategoricalDtype(categories=["a", "b", "c"])
542550

543-
# empty codes should not raise for floats
544-
Categorical.from_codes([], dtype.categories)
545-
546-
with pytest.raises(ValueError, match="codes need to be array-like integers"):
547-
Categorical.from_codes(codes, dtype.categories)
548-
549-
with pytest.raises(ValueError, match="codes need to be array-like integers"):
550-
Categorical.from_codes(codes, dtype=dtype)
551-
552-
codes = [1.1, 2.0, 0] # non-integer
553-
with pytest.raises(ValueError, match="codes need to be array-like integers"):
551+
msg = "codes need to be array-like integers"
552+
with pytest.raises(ValueError, match=msg):
554553
Categorical.from_codes(codes, dtype.categories)
555-
with pytest.raises(ValueError, match="codes need to be array-like integers"):
554+
with pytest.raises(ValueError, match=msg):
556555
Categorical.from_codes(codes, dtype=dtype)
557556

558557
def test_from_codes_with_dtype_raises(self):

0 commit comments

Comments
 (0)