Skip to content

Commit

Permalink
API: add "unique=" argument to MultiIndex.get_level_values()
Browse files Browse the repository at this point in the history
  • Loading branch information
toobaz committed Oct 16, 2017
1 parent 5bf7f9a commit 57aa7e6
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 7 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.21.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,7 @@ Other API Changes
- Pandas no longer registers matplotlib converters on import. The converters
will be registered and used when the first plot is draw (:issue:`17710`)
- Setting on a column with a scalar value and 0-len index now raises a ``ValueError`` (:issue:`16823`)
- :func:`MultiIndex.get_level_values` now supports the `unique` argument (:issue:`17896`)


.. _whatsnew_0210.deprecations:
Expand Down
20 changes: 13 additions & 7 deletions pandas/core/indexes/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ def _try_mi(k):

raise InvalidIndexError(key)

def _get_level_values(self, level):
def _get_level_values(self, level, unique=False):
"""
Return vector of label values for requested level,
equal to the length of the index
Expand All @@ -896,20 +896,24 @@ def _get_level_values(self, level):
Parameters
----------
level : int level
unique : bool
if True, drop duplicated values
Returns
-------
values : ndarray
"""

unique = self.levels[level]
values = self.levels[level]
labels = self.labels[level]
filled = algos.take_1d(unique._values, labels,
fill_value=unique._na_value)
values = unique._shallow_copy(filled)
if unique:
labels = np.unique(labels[labels != -1])
filled = algos.take_1d(values._values, labels,
fill_value=values._na_value)
values = values._shallow_copy(filled)
return values

def get_level_values(self, level):
def get_level_values(self, level, unique=False):
"""
Return vector of label values for requested level,
equal to the length of the index.
Expand All @@ -919,6 +923,8 @@ def get_level_values(self, level):
level : int or str
``level`` is either the integer position of the level in the
MultiIndex, or the name of the level.
unique : bool
if True, drop duplicated values
Returns
-------
Expand All @@ -942,7 +948,7 @@ def get_level_values(self, level):
Index(['d', 'e', 'f'], dtype='object', name='level_2')
"""
level = self._get_level_number(level)
values = self._get_level_values(level)
values = self._get_level_values(level, unique=unique)
return values

def format(self, space=2, sparsify=None, adjoin=True, names=False,
Expand Down
14 changes: 14 additions & 0 deletions pandas/tests/indexes/test_multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,13 @@ def test_get_level_values(self):
tm.assert_index_equal(result, expected)
assert result.name == 'first'

# with unique=True
result = self.index.get_level_values(0, unique=True)
expected = Index(['foo', 'bar', 'baz', 'qux'],
name='first')
tm.assert_index_equal(result, expected)
assert result.name == 'first'

result = self.index.get_level_values('first')
expected = self.index.get_level_values(0)
tm.assert_index_equal(result, expected)
Expand Down Expand Up @@ -988,6 +995,13 @@ def test_get_level_values_na(self):
values = index.get_level_values(0)
assert values.shape == (0, )

# with unique=True
arrays = [['a', 'b', 'b'], [2, np.nan, 2]]
index = pd.MultiIndex.from_arrays(arrays)
values = index.get_level_values(1, unique=True)
expected = np.array([2])
tm.assert_numpy_array_equal(values.values, expected)

def test_reorder_levels(self):
# this blows up
tm.assert_raises_regex(IndexError, '^Too many levels',
Expand Down

0 comments on commit 57aa7e6

Please sign in to comment.