diff --git a/RELEASE.rst b/RELEASE.rst index 53ced7a5403b1..f0a79b38bc1cf 100644 --- a/RELEASE.rst +++ b/RELEASE.rst @@ -135,8 +135,8 @@ pandas 0.5.1 - Handle min_periods=0 case in moving window functions (GH #365) - Fixed corner cases in DataFrame.apply/pivot with empty DataFrame (GH #378) - Fixed repr exception when Series name is a tuple - - Always return DateRange from asfreq (GH #390) - - + - Always return DateRange from `asfreq` (GH #390) + - Pass level names to `swaplavel` (GH #379) Thanks ------ diff --git a/pandas/core/index.py b/pandas/core/index.py index 3beab80881e82..e4e820af38fcb 100644 --- a/pandas/core/index.py +++ b/pandas/core/index.py @@ -73,6 +73,11 @@ def dtype(self): def nlevels(self): return 1 + @property + def names(self): + # for compat with multindex code + return [self.name] + @property def _constructor(self): return Index @@ -864,6 +869,9 @@ class MultiIndex(Index): labels : list or tuple of arrays Integers for each level designating which label at each location """ + # shadow property + names = None + def __new__(cls, levels=None, labels=None, sortorder=None, names=None): assert(len(levels) == len(labels)) if len(levels) == 0: @@ -1178,11 +1186,16 @@ def droplevel(self, level=0): new_levels.pop(level) new_labels = list(self.labels) new_labels.pop(level) + new_names = list(self.names) + new_names.pop(level) if len(new_levels) == 1: - return new_levels[0].take(new_labels[0]) + result = new_levels[0].take(new_labels[0]) + result.name = new_names[0] + return result else: - return MultiIndex(levels=new_levels, labels=new_labels) + return MultiIndex(levels=new_levels, labels=new_labels, + names=new_names) def swaplevel(self, i, j): """ diff --git a/pandas/tests/test_index.py b/pandas/tests/test_index.py index 8bb4e6c631ec5..840cfe44086c9 100644 --- a/pandas/tests/test_index.py +++ b/pandas/tests/test_index.py @@ -1074,6 +1074,16 @@ def test_droplevel_with_names(self): dropped = index.droplevel(0) self.assertEqual(dropped.name, 'second') + index = MultiIndex(levels=[Index(range(4)), + Index(range(4)), + Index(range(4))], + labels=[np.array([0, 0, 1, 2, 2, 2, 3, 3]), + np.array([0, 1, 0, 0, 0, 1, 0, 1]), + np.array([1, 0, 1, 1, 0, 0, 1, 0])], + names=['one', 'two', 'three']) + dropped = index.droplevel(0) + self.assertEqual(dropped.names, ['two', 'three']) + def test_insert(self): # key contained in all levels new_index = self.index.insert(0, ('bar', 'two')) diff --git a/pandas/tests/test_multilevel.py b/pandas/tests/test_multilevel.py index 615f160616e19..aa45255a2cd29 100644 --- a/pandas/tests/test_multilevel.py +++ b/pandas/tests/test_multilevel.py @@ -652,6 +652,17 @@ def test_multilevel_consolidate(self): df['Totals', ''] = df.sum(1) df = df.consolidate() + def test_ix_preserve_names(self): + result = self.ymd.ix[2000] + result2 = self.ymd['A'].ix[2000] + self.assertEquals(result.index.names, self.ymd.index.names[1:]) + self.assertEquals(result2.index.names, self.ymd.index.names[1:]) + + result = self.ymd.ix[2000, 2] + result2 = self.ymd['A'].ix[2000, 2] + self.assertEquals(result.index.name, self.ymd.index.names[2]) + self.assertEquals(result2.index.name, self.ymd.index.names[2]) + if __name__ == '__main__': # unittest.main()