Skip to content

Commit b9d5e2f

Browse files
committed
BUG: Fix Series constructor for Categorical with index
Fixes Series constructor so that ValueError is raised when a Categorical and index of different length are given.
1 parent ce77b79 commit b9d5e2f

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

doc/source/whatsnew/v0.23.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,7 @@ Reshaping
903903
- :func:`Series.rename` now accepts ``axis`` as a kwarg (:issue:`18589`)
904904
- Comparisons between :class:`Series` and :class:`Index` would return a ``Series`` with an incorrect name, ignoring the ``Index``'s name attribute (:issue:`19582`)
905905
- Bug in :func:`qcut` where datetime and timedelta data with ``NaT`` present raised a ``ValueError`` (:issue:`19768`)
906+
- Bug in :class:`Series` constructor with ``Categorical`` where a ```ValueError`` is not raised when an index of different length is given (:issue:`19342`)
906907

907908
Other
908909
^^^^^

pandas/core/series.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,11 @@ def __init__(self, data=None, index=None, dtype=None, name=None,
213213

214214
elif is_extension_array_dtype(data) and dtype is not None:
215215
# GH12574: Allow dtype=category only, otherwise error
216-
if not data.dtype.is_dtype(dtype):
217-
raise ValueError("Cannot specify a dtype '{}' with an "
218-
"extension array of a different "
219-
"dtype ('{}').".format(dtype,
220-
data.dtype))
216+
if ((dtype is not None) and
217+
not is_categorical_dtype(dtype)):
218+
raise ValueError("cannot specify a dtype with a "
219+
"Categorical unless "
220+
"dtype='category'")
221221

222222
elif (isinstance(data, types.GeneratorType) or
223223
(compat.PY3 and isinstance(data, map))):
@@ -235,6 +235,11 @@ def __init__(self, data=None, index=None, dtype=None, name=None,
235235
if not is_list_like(data):
236236
data = [data]
237237
index = com._default_index(len(data))
238+
else:
239+
if not is_scalar(data) and len(index) != len(data):
240+
raise ValueError('Length of passed values is {val}, '
241+
'index implies {ind}'
242+
.format(val=len(data), ind=len(index)))
238243

239244
# create/copy the manager
240245
if isinstance(data, SingleBlockManager):

pandas/tests/series/test_constructors.py

+14
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,20 @@ def test_constructor_default_index(self):
393393
s = Series([0, 1, 2])
394394
tm.assert_index_equal(s.index, pd.Index(np.arange(3)))
395395

396+
@pytest.mark.parametrize('input', [[1, 2, 3],
397+
(1, 2, 3),
398+
list(range(3)),
399+
pd.Categorical(['a', 'b', 'a']),
400+
(i for i in range(3)),
401+
map(lambda x: x, range(3))])
402+
def test_constructor_index_mismatch(self, input):
403+
# GH 19342
404+
# test that construction of a Series with an index of different length
405+
# raises an error
406+
msg = 'Length of passed values is 3, index implies 4'
407+
with pytest.raises(ValueError, message=msg):
408+
Series(input, index=np.arange(4))
409+
396410
def test_constructor_corner(self):
397411
df = tm.makeTimeDataFrame()
398412
objs = [df, df]

0 commit comments

Comments
 (0)