diff --git a/doc/source/whatsnew/v0.20.0.txt b/doc/source/whatsnew/v0.20.0.txt index c82dc370e3e71..3f72259c0838c 100644 --- a/doc/source/whatsnew/v0.20.0.txt +++ b/doc/source/whatsnew/v0.20.0.txt @@ -351,6 +351,8 @@ Bug Fixes - Bug in converting object elements of array-like objects to unsigned 64-bit integers (:issue:`4471`, :issue:`14982`) - Bug in ``pd.pivot_table()`` where no error was raised when values argument was not in the columns (:issue:`14938`) +- Bug in ``DataFrame.groupby().describe()`` when grouping on ``Index`` containing tuples (:issue:`14848`) +- Raise `ValueError` if creating a `MultiIndex` with tuples and not passing a list of names (:issue:`15110`) diff --git a/pandas/indexes/multi.py b/pandas/indexes/multi.py index 132543e0e386c..2afafaeb544d1 100644 --- a/pandas/indexes/multi.py +++ b/pandas/indexes/multi.py @@ -490,6 +490,10 @@ def _set_names(self, names, level=None, validate=True): that it only acts on copies """ + # GH 15110 + # Don't allow a single string for names in a MultiIndex + if names is not None and not is_list_like(names): + raise ValueError('Names should be list-like for a MultiIndex') names = list(names) if validate and level is not None and len(names) != len(level): diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index b00dc62206f57..8e61fa3a5fb66 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -1490,6 +1490,19 @@ def test_frame_describe_multikey(self): for name, group in groupedT: assert_frame_equal(result[name], group.describe()) + def test_frame_describe_tupleindex(self): + + # GH 14848 - regression from 0.19.0 to 0.19.1 + df1 = DataFrame({'x': [1, 2, 3, 4, 5] * 3, + 'y': [10, 20, 30, 40, 50] * 3, + 'z': [100, 200, 300, 400, 500] * 3}) + df1['k'] = [(0, 0, 1), (0, 1, 0), (1, 0, 0)] * 5 + df2 = df1.rename(columns={'k': 'key'}) + result = df1.groupby('k').describe() + expected = df2.groupby('key').describe() + expected.index.set_names(result.index.names, inplace=True) + assert_frame_equal(result, expected) + def test_frame_groupby(self): grouped = self.tsframe.groupby(lambda x: x.weekday()) diff --git a/pandas/tests/indexes/test_multi.py b/pandas/tests/indexes/test_multi.py index 16831219e0930..2861a1f56b24b 100644 --- a/pandas/tests/indexes/test_multi.py +++ b/pandas/tests/indexes/test_multi.py @@ -2554,3 +2554,12 @@ def test_unsortedindex(self): with assertRaises(KeyError): df.loc(axis=0)['q', :] + + def test_tuples_with_name_string(self): + # GH 15110 and GH 14848 + + li = [(0, 0, 1), (0, 1, 0), (1, 0, 0)] + with assertRaises(ValueError): + pd.Index(li, name='abc') + with assertRaises(ValueError): + pd.Index(li, name='a')