Skip to content

Commit 6f91db6

Browse files
committed
BUG: .unique() on MultiIndex: preserve names
closes #20568
1 parent d2ab407 commit 6f91db6

File tree

3 files changed

+24
-9
lines changed

3 files changed

+24
-9
lines changed

doc/source/whatsnew/v0.23.0.txt

+2
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,8 @@ MultiIndex
10691069
- Bug in :func:`MultiIndex.__contains__` where non-tuple keys would return ``True`` even if they had been dropped (:issue:`19027`)
10701070
- Bug in :func:`MultiIndex.set_labels` which would cause casting (and potentially clipping) of the new labels if the ``level`` argument is not 0 or a list like [0, 1, ... ] (:issue:`19057`)
10711071
- Bug in :func:`MultiIndex.get_level_values` which would return an invalid index on level of ints with missing values (:issue:`17924`)
1072+
- Bug in :func:`MultiIndex.unique` when called on empty :class:`MultiIndex` (:issue:`20568`)
1073+
- Bug in :func:`MultiIndex.unique` which would not preserve level names (:issue:`20570`)
10721074
- Bug in :func:`MultiIndex.remove_unused_levels` which would fill nan values (:issue:`18417`)
10731075
- Bug in :func:`MultiIndex.from_tuples` which would fail to take zipped tuples in python3 (:issue:`18434`)
10741076
- Bug in :func:`MultiIndex.get_loc` which would fail to automatically cast values between float and int (:issue:`18818`, :issue:`15994`)

pandas/core/indexes/multi.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -553,11 +553,10 @@ def __contains__(self, key):
553553
@Appender(_index_shared_docs['_shallow_copy'])
554554
def _shallow_copy(self, values=None, **kwargs):
555555
if values is not None:
556-
if 'name' in kwargs:
557-
kwargs['names'] = kwargs.pop('name', None)
556+
names = kwargs.pop('names', kwargs.pop('name', self.names))
558557
# discards freq
559558
kwargs.pop('freq', None)
560-
return MultiIndex.from_tuples(values, **kwargs)
559+
return MultiIndex.from_tuples(values, names=names, **kwargs)
561560
return self.view()
562561

563562
@cache_readonly

pandas/tests/indexes/test_multi.py

+20-6
Original file line numberDiff line numberDiff line change
@@ -2453,22 +2453,31 @@ def test_get_unique_index(self):
24532453
tm.assert_index_equal(result, expected)
24542454

24552455
def test_unique(self):
2456-
mi = pd.MultiIndex.from_arrays([[1, 2, 1, 2], [1, 1, 1, 2]])
2456+
mi = pd.MultiIndex.from_arrays([[1, 2, 1, 2], [1, 1, 1, 2]],
2457+
names=['first', 'second'])
24572458

24582459
res = mi.unique()
2459-
exp = pd.MultiIndex.from_arrays([[1, 2, 2], [1, 1, 2]])
2460+
exp = pd.MultiIndex.from_arrays([[1, 2, 2], [1, 1, 2]], names=mi.names)
24602461
tm.assert_index_equal(res, exp)
24612462

2462-
mi = pd.MultiIndex.from_arrays([list('aaaa'), list('abab')])
2463+
mi = pd.MultiIndex.from_arrays([list('aaaa'), list('abab')],
2464+
names=['first', 'second'])
24632465
res = mi.unique()
2464-
exp = pd.MultiIndex.from_arrays([list('aa'), list('ab')])
2466+
exp = pd.MultiIndex.from_arrays([list('aa'), list('ab')],
2467+
names=mi.names)
24652468
tm.assert_index_equal(res, exp)
24662469

2467-
mi = pd.MultiIndex.from_arrays([list('aaaa'), list('aaaa')])
2470+
mi = pd.MultiIndex.from_arrays([list('aaaa'), list('aaaa')],
2471+
names=['first', 'second'])
24682472
res = mi.unique()
2469-
exp = pd.MultiIndex.from_arrays([['a'], ['a']])
2473+
exp = pd.MultiIndex.from_arrays([['a'], ['a']], names=mi.names)
24702474
tm.assert_index_equal(res, exp)
24712475

2476+
# GH #20568 - empty MI
2477+
mi = pd.MultiIndex.from_arrays([[], []], names=['first', 'second'])
2478+
res = mi.unique()
2479+
tm.assert_index_equal(mi, res)
2480+
24722481
@pytest.mark.parametrize('level', [0, 'first', 1, 'second'])
24732482
def test_unique_level(self, level):
24742483
# GH #17896 - with level= argument
@@ -2483,6 +2492,11 @@ def test_unique_level(self, level):
24832492
expected = mi.get_level_values(level)
24842493
tm.assert_index_equal(result, expected)
24852494

2495+
# With empty MI
2496+
mi = pd.MultiIndex.from_arrays([[], []], names=['first', 'second'])
2497+
result = mi.unique(level=level)
2498+
expected = mi.get_level_values(level)
2499+
24862500
def test_unique_datetimelike(self):
24872501
idx1 = pd.DatetimeIndex(['2015-01-01', '2015-01-01', '2015-01-01',
24882502
'2015-01-01', 'NaT', 'NaT'])

0 commit comments

Comments
 (0)