Skip to content

Commit 57aa7e6

Browse files
committed
API: add "unique=" argument to MultiIndex.get_level_values()
closes pandas-dev#17896
1 parent 5bf7f9a commit 57aa7e6

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

doc/source/whatsnew/v0.21.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,7 @@ Other API Changes
792792
- Pandas no longer registers matplotlib converters on import. The converters
793793
will be registered and used when the first plot is draw (:issue:`17710`)
794794
- Setting on a column with a scalar value and 0-len index now raises a ``ValueError`` (:issue:`16823`)
795+
- :func:`MultiIndex.get_level_values` now supports the `unique` argument (:issue:`17896`)
795796

796797

797798
.. _whatsnew_0210.deprecations:

pandas/core/indexes/multi.py

+13-7
Original file line numberDiff line numberDiff line change
@@ -886,7 +886,7 @@ def _try_mi(k):
886886

887887
raise InvalidIndexError(key)
888888

889-
def _get_level_values(self, level):
889+
def _get_level_values(self, level, unique=False):
890890
"""
891891
Return vector of label values for requested level,
892892
equal to the length of the index
@@ -896,20 +896,24 @@ def _get_level_values(self, level):
896896
Parameters
897897
----------
898898
level : int level
899+
unique : bool
900+
if True, drop duplicated values
899901
900902
Returns
901903
-------
902904
values : ndarray
903905
"""
904906

905-
unique = self.levels[level]
907+
values = self.levels[level]
906908
labels = self.labels[level]
907-
filled = algos.take_1d(unique._values, labels,
908-
fill_value=unique._na_value)
909-
values = unique._shallow_copy(filled)
909+
if unique:
910+
labels = np.unique(labels[labels != -1])
911+
filled = algos.take_1d(values._values, labels,
912+
fill_value=values._na_value)
913+
values = values._shallow_copy(filled)
910914
return values
911915

912-
def get_level_values(self, level):
916+
def get_level_values(self, level, unique=False):
913917
"""
914918
Return vector of label values for requested level,
915919
equal to the length of the index.
@@ -919,6 +923,8 @@ def get_level_values(self, level):
919923
level : int or str
920924
``level`` is either the integer position of the level in the
921925
MultiIndex, or the name of the level.
926+
unique : bool
927+
if True, drop duplicated values
922928
923929
Returns
924930
-------
@@ -942,7 +948,7 @@ def get_level_values(self, level):
942948
Index(['d', 'e', 'f'], dtype='object', name='level_2')
943949
"""
944950
level = self._get_level_number(level)
945-
values = self._get_level_values(level)
951+
values = self._get_level_values(level, unique=unique)
946952
return values
947953

948954
def format(self, space=2, sparsify=None, adjoin=True, names=False,

pandas/tests/indexes/test_multi.py

+14
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,13 @@ def test_get_level_values(self):
942942
tm.assert_index_equal(result, expected)
943943
assert result.name == 'first'
944944

945+
# with unique=True
946+
result = self.index.get_level_values(0, unique=True)
947+
expected = Index(['foo', 'bar', 'baz', 'qux'],
948+
name='first')
949+
tm.assert_index_equal(result, expected)
950+
assert result.name == 'first'
951+
945952
result = self.index.get_level_values('first')
946953
expected = self.index.get_level_values(0)
947954
tm.assert_index_equal(result, expected)
@@ -988,6 +995,13 @@ def test_get_level_values_na(self):
988995
values = index.get_level_values(0)
989996
assert values.shape == (0, )
990997

998+
# with unique=True
999+
arrays = [['a', 'b', 'b'], [2, np.nan, 2]]
1000+
index = pd.MultiIndex.from_arrays(arrays)
1001+
values = index.get_level_values(1, unique=True)
1002+
expected = np.array([2])
1003+
tm.assert_numpy_array_equal(values.values, expected)
1004+
9911005
def test_reorder_levels(self):
9921006
# this blows up
9931007
tm.assert_raises_regex(IndexError, '^Too many levels',

0 commit comments

Comments
 (0)