Skip to content

Commit 1b3f381

Browse files
committed
BUG: MultiIndex.get_level_values() replaces NA by another value (#5074)
1 parent aa9d9b9 commit 1b3f381

File tree

4 files changed

+44
-1
lines changed

4 files changed

+44
-1
lines changed

doc/source/release.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,7 @@ Bug Fixes
569569
- Fixed a bug where default options were being overwritten in the option
570570
parser cleaning (:issue:`5121`).
571571
- Treat a list/ndarray identically for ``iloc`` indexing with list-like (:issue:`5006`)
572+
- Fix ``MultiIndex.get_level_values()`` with missing values (:issue:`5074`)
572573

573574
pandas 0.12.0
574575
-------------

pandas/core/index.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,10 @@ def values(self):
393393
def get_values(self):
394394
return self.values
395395

396+
def _na_value(self):
397+
# The expected NA value to use with this index.
398+
return np.nan
399+
396400
@property
397401
def is_monotonic(self):
398402
return self._engine.is_monotonic
@@ -2256,7 +2260,8 @@ def get_level_values(self, level):
22562260
num = self._get_level_number(level)
22572261
unique_vals = self.levels[num] # .values
22582262
labels = self.labels[num]
2259-
values = unique_vals.take(labels)
2263+
values = Index(com.take_1d(unique_vals.values, labels,
2264+
fill_value=unique_vals._na_value()))
22602265
values.name = self.names[num]
22612266
return values
22622267

pandas/tests/test_index.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,39 @@ def test_get_level_values(self):
14451445
expected = self.index.get_level_values(0)
14461446
self.assert_(np.array_equal(result, expected))
14471447

1448+
def test_get_level_values_na(self):
1449+
arrays = [['a', 'b', 'b'], [1, np.nan, 2]]
1450+
index = pd.MultiIndex.from_arrays(arrays)
1451+
values = index.get_level_values(1)
1452+
expected = [1, np.nan, 2]
1453+
assert_array_equal(values.values.astype(float), expected)
1454+
1455+
arrays = [['a', 'b', 'b'], [np.nan, np.nan, 2]]
1456+
index = pd.MultiIndex.from_arrays(arrays)
1457+
values = index.get_level_values(1)
1458+
expected = [np.nan, np.nan, 2]
1459+
assert_array_equal(values.values.astype(float), expected)
1460+
1461+
arrays = [[np.nan, np.nan, np.nan], ['a', np.nan, 1]]
1462+
index = pd.MultiIndex.from_arrays(arrays)
1463+
values = index.get_level_values(0)
1464+
expected = [np.nan, np.nan, np.nan]
1465+
assert_array_equal(values.values.astype(float), expected)
1466+
values = index.get_level_values(1)
1467+
expected = ['a', np.nan, 1]
1468+
assert_array_equal(values.values, expected)
1469+
1470+
arrays = [['a', 'b', 'b'], pd.DatetimeIndex([0, 1, pd.NaT])]
1471+
index = pd.MultiIndex.from_arrays(arrays)
1472+
values = index.get_level_values(1)
1473+
expected = pd.DatetimeIndex([0, 1, pd.NaT])
1474+
assert_array_equal(values.values, expected.values)
1475+
1476+
arrays = [[], []]
1477+
index = pd.MultiIndex.from_arrays(arrays)
1478+
values = index.get_level_values(0)
1479+
self.assertEqual(values.shape, (0,))
1480+
14481481
def test_reorder_levels(self):
14491482
# this blows up
14501483
assertRaisesRegexp(IndexError, '^Too many levels',

pandas/tseries/index.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,10 @@ def _mpl_repr(self):
495495
# how to represent ourselves to matplotlib
496496
return tslib.ints_to_pydatetime(self.asi8, self.tz)
497497

498+
def _na_value(self):
499+
# The expected NA value to use with this index.
500+
return tslib.NaT
501+
498502
def __unicode__(self):
499503
from pandas.core.format import _format_datetime64
500504
values = self.values

0 commit comments

Comments
 (0)