diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index c2abb70988dad..5f7d2af92e839 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -568,6 +568,7 @@ MultiIndex - Bug in :meth:`MultiIndex.union` not sorting when sort=None and index contains missing values (:issue:`49010`) - Bug in :meth:`MultiIndex.append` not checking names for equality (:issue:`48288`) - Bug in :meth:`MultiIndex.symmetric_difference` losing extension array (:issue:`48607`) +- Bug in :meth:`MultiIndex.value_counts` returning a :class:`Series` indexed by flat index of tuples instead of a :class:`MultiIndex` (:issue:`49558`) - I/O diff --git a/pandas/core/algorithms.py b/pandas/core/algorithms.py index 7494a8a54f9bb..7be5e4e33bf3a 100644 --- a/pandas/core/algorithms.py +++ b/pandas/core/algorithms.py @@ -871,6 +871,14 @@ def value_counts( result.name = name counts = result._values + elif isinstance(values, ABCMultiIndex): + # GH49558 + levels = list(range(values.nlevels)) + result = Series(index=values).groupby(level=levels, dropna=dropna).size() + # TODO: allow index names to remain (see discussion in GH49497) + result.index.names = [None] * values.nlevels + counts = result._values + else: values = _ensure_arraylike(values) keys, counts = value_counts_arraylike(values, dropna) diff --git a/pandas/tests/base/test_value_counts.py b/pandas/tests/base/test_value_counts.py index f6ad3f24434d3..dafbd9fee1b8e 100644 --- a/pandas/tests/base/test_value_counts.py +++ b/pandas/tests/base/test_value_counts.py @@ -29,8 +29,6 @@ def test_value_counts(index_or_series_obj): counter = collections.Counter(obj) expected = Series(dict(counter.most_common()), dtype=np.int64, name=obj.name) expected.index = expected.index.astype(obj.dtype) - if isinstance(obj, pd.MultiIndex): - expected.index = Index(expected.index) if not isinstance(result.dtype, np.dtype): # i.e IntegerDtype