From 99dbff4c1da5db3da98994a2efae4ff4a7d5d336 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Wed, 12 Feb 2020 10:29:00 -0600 Subject: [PATCH 01/18] Add test with NA --- pandas/tests/arrays/categorical/test_constructors.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pandas/tests/arrays/categorical/test_constructors.py b/pandas/tests/arrays/categorical/test_constructors.py index dbd8fd8df67c1..929c6e971dbea 100644 --- a/pandas/tests/arrays/categorical/test_constructors.py +++ b/pandas/tests/arrays/categorical/test_constructors.py @@ -458,6 +458,13 @@ def test_constructor_with_categorical_categories(self): result = Categorical(["a", "b"], categories=CategoricalIndex(["a", "b", "c"])) tm.assert_categorical_equal(result, expected) + def test_construction_with_na(self): + values = ["a", pd.NA] + result = Categorical(np.array(values, dtype=object)) + expected = Categorical(values) + + tm.assert_categorical_equal(result, expected) + def test_from_codes(self): # too few categories From 81516a6f843477a484b218fce7a5d410c69231f8 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Wed, 12 Feb 2020 14:03:42 -0600 Subject: [PATCH 02/18] Add GH issue --- pandas/tests/arrays/categorical/test_constructors.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/arrays/categorical/test_constructors.py b/pandas/tests/arrays/categorical/test_constructors.py index 929c6e971dbea..3854bbb633c65 100644 --- a/pandas/tests/arrays/categorical/test_constructors.py +++ b/pandas/tests/arrays/categorical/test_constructors.py @@ -459,6 +459,7 @@ def test_constructor_with_categorical_categories(self): tm.assert_categorical_equal(result, expected) def test_construction_with_na(self): + # https://github.com/pandas-dev/pandas/issues/31927 values = ["a", pd.NA] result = Categorical(np.array(values, dtype=object)) expected = Categorical(values) From 78d62f9bf5b33c5cad51d27d0f0a816f6ea54bde Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Wed, 12 Feb 2020 14:58:16 -0600 Subject: [PATCH 03/18] Check for NA --- pandas/_libs/hashtable_class_helper.pxi.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/_libs/hashtable_class_helper.pxi.in b/pandas/_libs/hashtable_class_helper.pxi.in index 6671375f628e7..01ce78199b60a 100644 --- a/pandas/_libs/hashtable_class_helper.pxi.in +++ b/pandas/_libs/hashtable_class_helper.pxi.in @@ -1032,7 +1032,8 @@ cdef class PyObjectHashTable(HashTable): val = values[i] hash(val) - if ignore_na and ((val != val or val is None) + if ignore_na and (((val == val) is (val != val)) + or (val != val or val is None) or (use_na_value and val == na_value)): # if missing values do not count as unique values (i.e. if # ignore_na is True), skip the hashtable entry for them, and From 38fede6aac7046ef66396c648f05648bb26688e1 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Wed, 12 Feb 2020 15:49:59 -0600 Subject: [PATCH 04/18] Update whatsnew --- doc/source/whatsnew/v1.0.2.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v1.0.2.rst b/doc/source/whatsnew/v1.0.2.rst index 0216007ea5ba8..860463a99fa2f 100644 --- a/doc/source/whatsnew/v1.0.2.rst +++ b/doc/source/whatsnew/v1.0.2.rst @@ -31,6 +31,7 @@ Bug fixes **Categorical** - Fixed bug where :meth:`Categorical.from_codes` improperly raised a ``ValueError`` when passed nullable integer codes. (:issue:`31779`) +- Fixed bug where :meth:`Categorical` constructor would raise a ``TypeError`` when given a numpy array containing ``NA``. (:issue:`31927`) **I/O** From 52466ab05d6820bbeb5b52c04f1f0f1e7b999000 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Wed, 12 Feb 2020 16:10:14 -0600 Subject: [PATCH 05/18] Add MultiIndex test --- pandas/tests/indexing/multiindex/test_multiindex.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pandas/tests/indexing/multiindex/test_multiindex.py b/pandas/tests/indexing/multiindex/test_multiindex.py index 0064187a94265..da4307477fb8e 100644 --- a/pandas/tests/indexing/multiindex/test_multiindex.py +++ b/pandas/tests/indexing/multiindex/test_multiindex.py @@ -111,3 +111,13 @@ def test_nested_tuples_duplicates(self): df3 = df.copy(deep=True) df3.loc[[(dti[0], "a")], "c2"] = 1.0 tm.assert_frame_equal(df3, expected) + + def test_multiindex_from_product_contains_na(self): + # https://github.com/pandas-dev/pandas/issues/31883 + values1 = [np.array([0.0, pd.NA], dtype="object"), ["a", "b"]] + values2 = [np.array([0.0, np.nan], dtype="object"), ["a", "b"]] + + result = pd.MultiIndex.from_product(values1) + expected = pd.MultiIndex.from_product(values2) + + tm.assert_index_equal(result, expected) From 1a71728866f3d76ac07d892a7918e7331eade05a Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Wed, 12 Feb 2020 16:16:58 -0600 Subject: [PATCH 06/18] whatsnew for MultiIndex --- doc/source/whatsnew/v1.0.2.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/source/whatsnew/v1.0.2.rst b/doc/source/whatsnew/v1.0.2.rst index 860463a99fa2f..9fc68ee54d387 100644 --- a/doc/source/whatsnew/v1.0.2.rst +++ b/doc/source/whatsnew/v1.0.2.rst @@ -33,6 +33,10 @@ Bug fixes - Fixed bug where :meth:`Categorical.from_codes` improperly raised a ``ValueError`` when passed nullable integer codes. (:issue:`31779`) - Fixed bug where :meth:`Categorical` constructor would raise a ``TypeError`` when given a numpy array containing ``NA``. (:issue:`31927`) +**MultiIndex** + +- Fixed bug where :meth:`MultiIndex.from_product` would break when handling numpy object arrays containing ``NA``. (:issue:`31883`) + **I/O** - Using ``pd.NA`` with :meth:`DataFrame.to_json` now correctly outputs a null value instead of an empty object (:issue:`31615`) From bad5be38fad0508aa9b2951e73d320747dfb55c9 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Wed, 12 Feb 2020 17:25:28 -0600 Subject: [PATCH 07/18] Parametrize test --- pandas/tests/arrays/categorical/test_constructors.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/tests/arrays/categorical/test_constructors.py b/pandas/tests/arrays/categorical/test_constructors.py index 3854bbb633c65..d69eebc1710a6 100644 --- a/pandas/tests/arrays/categorical/test_constructors.py +++ b/pandas/tests/arrays/categorical/test_constructors.py @@ -458,9 +458,9 @@ def test_constructor_with_categorical_categories(self): result = Categorical(["a", "b"], categories=CategoricalIndex(["a", "b", "c"])) tm.assert_categorical_equal(result, expected) - def test_construction_with_na(self): + def test_construction_with_null(self, nulls_fixture): # https://github.com/pandas-dev/pandas/issues/31927 - values = ["a", pd.NA] + values = ["a", nulls_fixture] result = Categorical(np.array(values, dtype=object)) expected = Categorical(values) From b051bf08750acfe036800c7f0ffa229e82c39e91 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Wed, 12 Feb 2020 17:28:54 -0600 Subject: [PATCH 08/18] Use pd.NA --- pandas/_libs/hashtable_class_helper.pxi.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pandas/_libs/hashtable_class_helper.pxi.in b/pandas/_libs/hashtable_class_helper.pxi.in index 01ce78199b60a..b733277f03543 100644 --- a/pandas/_libs/hashtable_class_helper.pxi.in +++ b/pandas/_libs/hashtable_class_helper.pxi.in @@ -11,6 +11,8 @@ WARNING: DO NOT edit .pxi FILE directly, .pxi is generated from .pxi.in from pandas._libs.tslibs.util cimport get_c_string +import pandas as pd + {{py: # name, dtype, c_type @@ -1032,7 +1034,7 @@ cdef class PyObjectHashTable(HashTable): val = values[i] hash(val) - if ignore_na and (((val == val) is (val != val)) + if ignore_na and ((val is pd.NA) or (val != val or val is None) or (use_na_value and val == na_value)): # if missing values do not count as unique values (i.e. if From 563b673e813da323507b31ce2e9227757ce424dc Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Wed, 12 Feb 2020 18:13:07 -0600 Subject: [PATCH 09/18] Import C_NA --- pandas/_libs/hashtable_class_helper.pxi.in | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pandas/_libs/hashtable_class_helper.pxi.in b/pandas/_libs/hashtable_class_helper.pxi.in index b733277f03543..0e1a78e1b917d 100644 --- a/pandas/_libs/hashtable_class_helper.pxi.in +++ b/pandas/_libs/hashtable_class_helper.pxi.in @@ -10,8 +10,7 @@ WARNING: DO NOT edit .pxi FILE directly, .pxi is generated from .pxi.in # ---------------------------------------------------------------------- from pandas._libs.tslibs.util cimport get_c_string - -import pandas as pd +from pandas._libs.missing cimport C_NA {{py: @@ -1034,7 +1033,7 @@ cdef class PyObjectHashTable(HashTable): val = values[i] hash(val) - if ignore_na and ((val is pd.NA) + if ignore_na and ((val is C_NA) or (val != val or val is None) or (use_na_value and val == na_value)): # if missing values do not count as unique values (i.e. if From 7da4e44f73570acdac507c1d3f2479633efef291 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Sun, 16 Feb 2020 09:39:01 -0600 Subject: [PATCH 10/18] Edit release note --- doc/source/whatsnew/v1.0.2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.0.2.rst b/doc/source/whatsnew/v1.0.2.rst index 9fc68ee54d387..4cf2e774827cb 100644 --- a/doc/source/whatsnew/v1.0.2.rst +++ b/doc/source/whatsnew/v1.0.2.rst @@ -31,7 +31,7 @@ Bug fixes **Categorical** - Fixed bug where :meth:`Categorical.from_codes` improperly raised a ``ValueError`` when passed nullable integer codes. (:issue:`31779`) -- Fixed bug where :meth:`Categorical` constructor would raise a ``TypeError`` when given a numpy array containing ``NA``. (:issue:`31927`) +- Fixed bug where :meth:`Categorical` constructor would raise a ``TypeError`` when given a numpy array containing :class:`NA`. (:issue:`31927`) **MultiIndex** From d1a953b0e296fb75f813652171e94305906f16bd Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Sun, 16 Feb 2020 09:43:44 -0600 Subject: [PATCH 11/18] Align conditions --- pandas/_libs/hashtable_class_helper.pxi.in | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pandas/_libs/hashtable_class_helper.pxi.in b/pandas/_libs/hashtable_class_helper.pxi.in index 0e1a78e1b917d..811025a4b5764 100644 --- a/pandas/_libs/hashtable_class_helper.pxi.in +++ b/pandas/_libs/hashtable_class_helper.pxi.in @@ -1033,9 +1033,12 @@ cdef class PyObjectHashTable(HashTable): val = values[i] hash(val) - if ignore_na and ((val is C_NA) - or (val != val or val is None) - or (use_na_value and val == na_value)): + if ignore_na and ( + (val is C_NA) + or (val != val) + or (val is None) + or (use_na_value and val == na_value) + ): # if missing values do not count as unique values (i.e. if # ignore_na is True), skip the hashtable entry for them, and # replace the corresponding label with na_sentinel From baab1d578f76713a2853642578cb9c26dc9d42e7 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Sun, 16 Feb 2020 10:01:37 -0600 Subject: [PATCH 12/18] Construct from tuples in test --- pandas/tests/indexing/multiindex/test_multiindex.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pandas/tests/indexing/multiindex/test_multiindex.py b/pandas/tests/indexing/multiindex/test_multiindex.py index da4307477fb8e..49915a473df0a 100644 --- a/pandas/tests/indexing/multiindex/test_multiindex.py +++ b/pandas/tests/indexing/multiindex/test_multiindex.py @@ -114,10 +114,10 @@ def test_nested_tuples_duplicates(self): def test_multiindex_from_product_contains_na(self): # https://github.com/pandas-dev/pandas/issues/31883 - values1 = [np.array([0.0, pd.NA], dtype="object"), ["a", "b"]] - values2 = [np.array([0.0, np.nan], dtype="object"), ["a", "b"]] + values = [np.array([0.0, pd.NA], dtype="object"), ["a", "b"]] + tuples = [(0.0, "a"), (0.0, "b"), (np.nan, "a"), (np.nan, "b")] - result = pd.MultiIndex.from_product(values1) - expected = pd.MultiIndex.from_product(values2) + result = pd.MultiIndex.from_product(values) + expected = pd.MultiIndex.from_tuples(tuples) tm.assert_index_equal(result, expected) From 2d45b216bb2f7a2b4e247b8ce0e908a4da7bafa4 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Sun, 16 Feb 2020 15:47:44 -0600 Subject: [PATCH 13/18] Add a string --- pandas/tests/arrays/categorical/test_constructors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/arrays/categorical/test_constructors.py b/pandas/tests/arrays/categorical/test_constructors.py index d69eebc1710a6..622479541fd62 100644 --- a/pandas/tests/arrays/categorical/test_constructors.py +++ b/pandas/tests/arrays/categorical/test_constructors.py @@ -460,7 +460,7 @@ def test_constructor_with_categorical_categories(self): def test_construction_with_null(self, nulls_fixture): # https://github.com/pandas-dev/pandas/issues/31927 - values = ["a", nulls_fixture] + values = ["a", nulls_fixture, "b"] result = Categorical(np.array(values, dtype=object)) expected = Categorical(values) From 14a737d57cab44663ff6c9c9373ffcec9459c220 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Mon, 17 Feb 2020 12:19:22 -0600 Subject: [PATCH 14/18] Use checknull --- pandas/_libs/hashtable_class_helper.pxi.in | 6 ++---- pandas/_libs/missing.pyx | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pandas/_libs/hashtable_class_helper.pxi.in b/pandas/_libs/hashtable_class_helper.pxi.in index 811025a4b5764..9bbc71c27ffe3 100644 --- a/pandas/_libs/hashtable_class_helper.pxi.in +++ b/pandas/_libs/hashtable_class_helper.pxi.in @@ -10,7 +10,7 @@ WARNING: DO NOT edit .pxi FILE directly, .pxi is generated from .pxi.in # ---------------------------------------------------------------------- from pandas._libs.tslibs.util cimport get_c_string -from pandas._libs.missing cimport C_NA +from pandas._libs.missing cimport checknull {{py: @@ -1034,9 +1034,7 @@ cdef class PyObjectHashTable(HashTable): hash(val) if ignore_na and ( - (val is C_NA) - or (val != val) - or (val is None) + checknull(val) or (use_na_value and val == na_value) ): # if missing values do not count as unique values (i.e. if diff --git a/pandas/_libs/missing.pyx b/pandas/_libs/missing.pyx index 4d17a6f883c1c..cfdc4ee4540e2 100644 --- a/pandas/_libs/missing.pyx +++ b/pandas/_libs/missing.pyx @@ -33,6 +33,7 @@ cpdef bint checknull(object val): Return boolean describing of the input is NA-like, defined here as any of: - None + - pd.NA - nan - NaT - np.datetime64 representation of NaT From a54fe0d51ee910692e03ec2f1b37053662e06d5d Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Mon, 17 Feb 2020 13:40:21 -0600 Subject: [PATCH 15/18] Revert "Use checknull" This reverts commit 14a737d57cab44663ff6c9c9373ffcec9459c220. --- pandas/_libs/hashtable_class_helper.pxi.in | 6 ++++-- pandas/_libs/missing.pyx | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pandas/_libs/hashtable_class_helper.pxi.in b/pandas/_libs/hashtable_class_helper.pxi.in index 9bbc71c27ffe3..811025a4b5764 100644 --- a/pandas/_libs/hashtable_class_helper.pxi.in +++ b/pandas/_libs/hashtable_class_helper.pxi.in @@ -10,7 +10,7 @@ WARNING: DO NOT edit .pxi FILE directly, .pxi is generated from .pxi.in # ---------------------------------------------------------------------- from pandas._libs.tslibs.util cimport get_c_string -from pandas._libs.missing cimport checknull +from pandas._libs.missing cimport C_NA {{py: @@ -1034,7 +1034,9 @@ cdef class PyObjectHashTable(HashTable): hash(val) if ignore_na and ( - checknull(val) + (val is C_NA) + or (val != val) + or (val is None) or (use_na_value and val == na_value) ): # if missing values do not count as unique values (i.e. if diff --git a/pandas/_libs/missing.pyx b/pandas/_libs/missing.pyx index cfdc4ee4540e2..4d17a6f883c1c 100644 --- a/pandas/_libs/missing.pyx +++ b/pandas/_libs/missing.pyx @@ -33,7 +33,6 @@ cpdef bint checknull(object val): Return boolean describing of the input is NA-like, defined here as any of: - None - - pd.NA - nan - NaT - np.datetime64 representation of NaT From 78e38ec60805b784ee80d6e7156cd571c4bb4054 Mon Sep 17 00:00:00 2001 From: Daniel Saxton <2658661+dsaxton@users.noreply.github.com> Date: Tue, 18 Feb 2020 09:45:32 -0600 Subject: [PATCH 16/18] Update doc/source/whatsnew/v1.0.2.rst Co-Authored-By: Joris Van den Bossche --- doc/source/whatsnew/v1.0.2.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.0.2.rst b/doc/source/whatsnew/v1.0.2.rst index b15c6076a71d2..3d27e340961a4 100644 --- a/doc/source/whatsnew/v1.0.2.rst +++ b/doc/source/whatsnew/v1.0.2.rst @@ -31,7 +31,7 @@ Bug fixes **Categorical** - Fixed bug where :meth:`Categorical.from_codes` improperly raised a ``ValueError`` when passed nullable integer codes. (:issue:`31779`) -- Fixed bug where :meth:`Categorical` constructor would raise a ``TypeError`` when given a numpy array containing :class:`NA`. (:issue:`31927`) +- Fixed bug where :meth:`Categorical` constructor would raise a ``TypeError`` when given a numpy array containing ``pd.NA``. (:issue:`31927`) - Bug in :class:`Categorical` that would ignore or crash when calling :meth:`Series.replace` with a list-like ``to_replace`` (:issue:`31720`) **MultiIndex** @@ -57,4 +57,4 @@ Bug fixes Contributors ~~~~~~~~~~~~ -.. contributors:: v1.0.1..v1.0.2|HEAD \ No newline at end of file +.. contributors:: v1.0.1..v1.0.2|HEAD From 0efcdb0fb64d706fae8b0b4740b54d0fc3df7c41 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Tue, 18 Feb 2020 18:40:36 -0600 Subject: [PATCH 17/18] Take out MultiIndex stuff --- doc/source/whatsnew/v1.0.2.rst | 4 ---- pandas/tests/indexing/multiindex/test_multiindex.py | 10 ---------- 2 files changed, 14 deletions(-) diff --git a/doc/source/whatsnew/v1.0.2.rst b/doc/source/whatsnew/v1.0.2.rst index 3d27e340961a4..8a2f50dce4497 100644 --- a/doc/source/whatsnew/v1.0.2.rst +++ b/doc/source/whatsnew/v1.0.2.rst @@ -34,10 +34,6 @@ Bug fixes - Fixed bug where :meth:`Categorical` constructor would raise a ``TypeError`` when given a numpy array containing ``pd.NA``. (:issue:`31927`) - Bug in :class:`Categorical` that would ignore or crash when calling :meth:`Series.replace` with a list-like ``to_replace`` (:issue:`31720`) -**MultiIndex** - -- Fixed bug where :meth:`MultiIndex.from_product` would break when handling numpy object arrays containing ``NA``. (:issue:`31883`) - **I/O** - Using ``pd.NA`` with :meth:`DataFrame.to_json` now correctly outputs a null value instead of an empty object (:issue:`31615`) diff --git a/pandas/tests/indexing/multiindex/test_multiindex.py b/pandas/tests/indexing/multiindex/test_multiindex.py index 49915a473df0a..0064187a94265 100644 --- a/pandas/tests/indexing/multiindex/test_multiindex.py +++ b/pandas/tests/indexing/multiindex/test_multiindex.py @@ -111,13 +111,3 @@ def test_nested_tuples_duplicates(self): df3 = df.copy(deep=True) df3.loc[[(dti[0], "a")], "c2"] = 1.0 tm.assert_frame_equal(df3, expected) - - def test_multiindex_from_product_contains_na(self): - # https://github.com/pandas-dev/pandas/issues/31883 - values = [np.array([0.0, pd.NA], dtype="object"), ["a", "b"]] - tuples = [(0.0, "a"), (0.0, "b"), (np.nan, "a"), (np.nan, "b")] - - result = pd.MultiIndex.from_product(values) - expected = pd.MultiIndex.from_tuples(tuples) - - tm.assert_index_equal(result, expected) From d50f963ce0153a53b15bb026924db5fb0f756310 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Sat, 22 Feb 2020 22:29:53 -0600 Subject: [PATCH 18/18] Parametrize and hard code --- pandas/tests/arrays/categorical/test_constructors.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pandas/tests/arrays/categorical/test_constructors.py b/pandas/tests/arrays/categorical/test_constructors.py index 622479541fd62..d5537359d6948 100644 --- a/pandas/tests/arrays/categorical/test_constructors.py +++ b/pandas/tests/arrays/categorical/test_constructors.py @@ -458,11 +458,15 @@ def test_constructor_with_categorical_categories(self): result = Categorical(["a", "b"], categories=CategoricalIndex(["a", "b", "c"])) tm.assert_categorical_equal(result, expected) - def test_construction_with_null(self, nulls_fixture): + @pytest.mark.parametrize("klass", [lambda x: np.array(x, dtype=object), list]) + def test_construction_with_null(self, klass, nulls_fixture): # https://github.com/pandas-dev/pandas/issues/31927 - values = ["a", nulls_fixture, "b"] - result = Categorical(np.array(values, dtype=object)) - expected = Categorical(values) + values = klass(["a", nulls_fixture, "b"]) + result = Categorical(values) + + dtype = CategoricalDtype(["a", "b"]) + codes = [0, -1, 1] + expected = Categorical.from_codes(codes=codes, dtype=dtype) tm.assert_categorical_equal(result, expected)