Skip to content

Commit 9089b69

Browse files
committed
BUG: .unique() on MultiIndex: preserve names
closes pandas-dev#20308 closes pandas-dev#20570
1 parent d2ab407 commit 9089b69

File tree

3 files changed

+26
-10
lines changed

3 files changed

+26
-10
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

+22-7
Original file line numberDiff line numberDiff line change
@@ -2452,23 +2452,33 @@ def test_get_unique_index(self):
24522452
assert result.unique
24532453
tm.assert_index_equal(result, expected)
24542454

2455-
def test_unique(self):
2456-
mi = pd.MultiIndex.from_arrays([[1, 2, 1, 2], [1, 1, 1, 2]])
2455+
@pytest.mark.parametrize('names', [None, ['first', 'second']])
2456+
def test_unique(self, names):
2457+
mi = pd.MultiIndex.from_arrays([[1, 2, 1, 2], [1, 1, 1, 2]],
2458+
names=names)
24572459

24582460
res = mi.unique()
2459-
exp = pd.MultiIndex.from_arrays([[1, 2, 2], [1, 1, 2]])
2461+
exp = pd.MultiIndex.from_arrays([[1, 2, 2], [1, 1, 2]], names=mi.names)
24602462
tm.assert_index_equal(res, exp)
24612463

2462-
mi = pd.MultiIndex.from_arrays([list('aaaa'), list('abab')])
2464+
mi = pd.MultiIndex.from_arrays([list('aaaa'), list('abab')],
2465+
names=names)
24632466
res = mi.unique()
2464-
exp = pd.MultiIndex.from_arrays([list('aa'), list('ab')])
2467+
exp = pd.MultiIndex.from_arrays([list('aa'), list('ab')],
2468+
names=mi.names)
24652469
tm.assert_index_equal(res, exp)
24662470

2467-
mi = pd.MultiIndex.from_arrays([list('aaaa'), list('aaaa')])
2471+
mi = pd.MultiIndex.from_arrays([list('aaaa'), list('aaaa')],
2472+
names=names)
24682473
res = mi.unique()
2469-
exp = pd.MultiIndex.from_arrays([['a'], ['a']])
2474+
exp = pd.MultiIndex.from_arrays([['a'], ['a']], names=mi.names)
24702475
tm.assert_index_equal(res, exp)
24712476

2477+
# GH #20568 - empty MI
2478+
mi = pd.MultiIndex.from_arrays([[], []], names=names)
2479+
res = mi.unique()
2480+
tm.assert_index_equal(mi, res)
2481+
24722482
@pytest.mark.parametrize('level', [0, 'first', 1, 'second'])
24732483
def test_unique_level(self, level):
24742484
# GH #17896 - with level= argument
@@ -2483,6 +2493,11 @@ def test_unique_level(self, level):
24832493
expected = mi.get_level_values(level)
24842494
tm.assert_index_equal(result, expected)
24852495

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

0 commit comments

Comments
 (0)