diff --git a/doc/source/release.rst b/doc/source/release.rst index fa1d1bef333d4..267f373a9e534 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -222,6 +222,7 @@ Bug Fixes - Bug in preserving frequency across Timestamp addition/subtraction (:issue:`4547`) - Bug in indexing: empty list lookup caused ``IndexError`` exceptions (:issue:`6536`, :issue:`6551`) - Series.quantile raising on an ``object`` dtype (:issue:`6555`) +- Bug in ``.xs`` with a ``nan`` in level when dropped (:issue:`6574`) pandas 0.13.1 ------------- diff --git a/pandas/core/index.py b/pandas/core/index.py index 30e18d239d950..3bc3783fffcbd 100644 --- a/pandas/core/index.py +++ b/pandas/core/index.py @@ -2947,7 +2947,13 @@ def droplevel(self, level=0): new_names.pop(i) if len(new_levels) == 1: + + # set nan if needed + mask = new_labels[0] == -1 result = new_levels[0].take(new_labels[0]) + if mask.any(): + np.putmask(result, mask, np.nan) + result.name = new_names[0] return result else: diff --git a/pandas/tests/test_multilevel.py b/pandas/tests/test_multilevel.py index 1e1d91d0db866..96272bab18dc2 100644 --- a/pandas/tests/test_multilevel.py +++ b/pandas/tests/test_multilevel.py @@ -391,6 +391,22 @@ def test_xs(self): assert_series_equal(xs, xs2) assert_almost_equal(xs.values, self.frame.values[4]) + # GH 6574 + # missing values in returned index should be preserrved + acc = [ + ('a','abcde',1), + ('b','bbcde',2), + ('y','yzcde',25), + ('z','xbcde',24), + ('z',None,26), + ('z','zbcde',25), + ('z','ybcde',26), + ] + df = DataFrame(acc, columns=['a1','a2','cnt']).set_index(['a1','a2']) + expected = DataFrame({ 'cnt' : [24,26,25,26] }, index=Index(['xbcde',np.nan,'zbcde','ybcde'],name='a2')) + result = df.xs('z',level='a1') + assert_frame_equal(result, expected) + def test_xs_partial(self): result = self.frame.xs('foo') result2 = self.frame.ix['foo']