From 9bfd321fecf5c1791c8a4d3f84e5dd6edfd64fff Mon Sep 17 00:00:00 2001 From: Drew Fustin Date: Tue, 15 Mar 2016 20:31:55 -0500 Subject: [PATCH 1/5] Allow dtype='category' for Series with Categorical --- pandas/core/series.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index d339a93a3ed9b..a0693e97a9360 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -32,6 +32,7 @@ from pandas.core import generic, base from pandas.core.internals import SingleBlockManager from pandas.core.categorical import Categorical, CategoricalAccessor +from pandas.core.dtypes import CategoricalDtype import pandas.core.strings as strings from pandas.tseries.common import (maybe_to_datetimelike, CombinedDatetimelikeProperties) @@ -195,9 +196,11 @@ def __init__(self, data=None, index=None, dtype=None, name=None, else: data = data.reindex(index, copy=copy) elif isinstance(data, Categorical): - if dtype is not None: + # Allow dtype=category only, otherwise error + if (dtype is not None) and (not isinstance(dtype, CategoricalDtype)): raise ValueError("cannot specify a dtype with a " - "Categorical") + "Categorical unless " + "dtype='category'") elif (isinstance(data, types.GeneratorType) or (compat.PY3 and isinstance(data, map))): data = list(data) From d7f927f3a7a9b76b6271d2c98bab5c5eec29a974 Mon Sep 17 00:00:00 2001 From: Drew Fustin Date: Tue, 15 Mar 2016 21:42:53 -0500 Subject: [PATCH 2/5] BUG: fixed to allow dtype=category when Series with Categorical is created --- doc/source/whatsnew/v0.18.1.txt | 2 ++ pandas/tests/test_dtypes.py | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/doc/source/whatsnew/v0.18.1.txt b/doc/source/whatsnew/v0.18.1.txt index a3e20879a2f58..f382efa90cbc0 100644 --- a/doc/source/whatsnew/v0.18.1.txt +++ b/doc/source/whatsnew/v0.18.1.txt @@ -93,3 +93,5 @@ Bug Fixes - Bug in ``value_counts`` when ``normalize=True`` and ``dropna=True`` where nulls still contributed to the normalized count (:issue:`12558`) - Bug in ``CategoricalIndex.get_loc`` returns different result from regular ``Index`` (:issue:`12531`) + +- Bug in ``Series`` when Series with Categorical is created with dtype specified (:issue:`12574`) diff --git a/pandas/tests/test_dtypes.py b/pandas/tests/test_dtypes.py index 943e7c92d988b..b561817d2857b 100644 --- a/pandas/tests/test_dtypes.py +++ b/pandas/tests/test_dtypes.py @@ -80,6 +80,13 @@ def test_basic(self): self.assertFalse(is_categorical(np.dtype('float64'))) self.assertFalse(is_categorical(1.0)) + def test_series_with_dtype(self): + self.assertRaises( + ValueError, lambda: Series(Categorical([1, 2, 3]), dtype='foo')) + s = Series(Categorical([1, 2, 3]), dtype='category') + self.assertTrue(is_categorical_dtype(s)) + self.assertTrue(is_categorical_dtype(s.dtype)) + class TestDatetimeTZDtype(Base, tm.TestCase): From ed42b87d6f8643d7ff9dd2cac1422bbe61b20edb Mon Sep 17 00:00:00 2001 From: Drew Fustin Date: Tue, 15 Mar 2016 21:50:55 -0500 Subject: [PATCH 3/5] BUG: fixed to allow dtype=category when Series with Categorical is created --- pandas/core/series.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index a0693e97a9360..89bd4eaded2e6 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -197,7 +197,8 @@ def __init__(self, data=None, index=None, dtype=None, name=None, data = data.reindex(index, copy=copy) elif isinstance(data, Categorical): # Allow dtype=category only, otherwise error - if (dtype is not None) and (not isinstance(dtype, CategoricalDtype)): + if ((dtype is not None) and + not isinstance(dtype, CategoricalDtype)): raise ValueError("cannot specify a dtype with a " "Categorical unless " "dtype='category'") From fd07315d9d780b9e70ed645e3a3e3e78cc1e4409 Mon Sep 17 00:00:00 2001 From: Drew Fustin Date: Tue, 15 Mar 2016 21:53:03 -0500 Subject: [PATCH 4/5] BUG: fixed to allow dtype=category when Series with Categorical is created --- pandas/tests/test_dtypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/test_dtypes.py b/pandas/tests/test_dtypes.py index b561817d2857b..6b73ee1a14b24 100644 --- a/pandas/tests/test_dtypes.py +++ b/pandas/tests/test_dtypes.py @@ -82,7 +82,7 @@ def test_basic(self): def test_series_with_dtype(self): self.assertRaises( - ValueError, lambda: Series(Categorical([1, 2, 3]), dtype='foo')) + ValueError, lambda: Series(Categorical([1, 2, 3]), dtype='int64')) s = Series(Categorical([1, 2, 3]), dtype='category') self.assertTrue(is_categorical_dtype(s)) self.assertTrue(is_categorical_dtype(s.dtype)) From ca1b9e77f0e0c72f6cd9c07dbbcf386c63998c10 Mon Sep 17 00:00:00 2001 From: Drew Fustin Date: Tue, 15 Mar 2016 22:55:17 -0500 Subject: [PATCH 5/5] BUG: fixed to allow dtype=category when Series with Categorical is created --- pandas/core/series.py | 5 ++--- pandas/tests/series/test_constructors.py | 11 +++++++++++ pandas/tests/test_dtypes.py | 7 ------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index 89bd4eaded2e6..649d5dbe8f384 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -32,7 +32,6 @@ from pandas.core import generic, base from pandas.core.internals import SingleBlockManager from pandas.core.categorical import Categorical, CategoricalAccessor -from pandas.core.dtypes import CategoricalDtype import pandas.core.strings as strings from pandas.tseries.common import (maybe_to_datetimelike, CombinedDatetimelikeProperties) @@ -196,9 +195,9 @@ def __init__(self, data=None, index=None, dtype=None, name=None, else: data = data.reindex(index, copy=copy) elif isinstance(data, Categorical): - # Allow dtype=category only, otherwise error + # GH12574: Allow dtype=category only, otherwise error if ((dtype is not None) and - not isinstance(dtype, CategoricalDtype)): + not is_categorical_dtype(dtype)): raise ValueError("cannot specify a dtype with a " "Categorical unless " "dtype='category'") diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index 43e47ae121408..356267630b274 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -139,6 +139,17 @@ def test_constructor_categorical(self): res = Series(cat) self.assertTrue(res.values.equals(cat)) + # GH12574 + self.assertRaises( + ValueError, lambda: Series(pd.Categorical([1, 2, 3]), + dtype='int64')) + cat = Series(pd.Categorical([1, 2, 3]), dtype='category') + self.assertTrue(com.is_categorical_dtype(cat)) + self.assertTrue(com.is_categorical_dtype(cat.dtype)) + s = Series([1, 2, 3], dtype='category') + self.assertTrue(com.is_categorical_dtype(s)) + self.assertTrue(com.is_categorical_dtype(s.dtype)) + def test_constructor_maskedarray(self): data = ma.masked_all((3, ), dtype=float) result = Series(data) diff --git a/pandas/tests/test_dtypes.py b/pandas/tests/test_dtypes.py index 6b73ee1a14b24..943e7c92d988b 100644 --- a/pandas/tests/test_dtypes.py +++ b/pandas/tests/test_dtypes.py @@ -80,13 +80,6 @@ def test_basic(self): self.assertFalse(is_categorical(np.dtype('float64'))) self.assertFalse(is_categorical(1.0)) - def test_series_with_dtype(self): - self.assertRaises( - ValueError, lambda: Series(Categorical([1, 2, 3]), dtype='int64')) - s = Series(Categorical([1, 2, 3]), dtype='category') - self.assertTrue(is_categorical_dtype(s)) - self.assertTrue(is_categorical_dtype(s.dtype)) - class TestDatetimeTZDtype(Base, tm.TestCase):