Skip to content

Commit 51f4e02

Browse files
committed
ENH: enable call delevel with standard index, GH #393
1 parent b7c3d2c commit 51f4e02

File tree

3 files changed

+28
-15
lines changed

3 files changed

+28
-15
lines changed

RELEASE.rst

+2
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ pandas 0.5.1
9999
- Improve performance of `MultiIndex.from_tuples`
100100
- Can pass multiple levels to `stack` and `unstack` (GH #370)
101101
- Can pass multiple values columns to `pivot_table` (GH #381)
102+
- Can call `DataFrame.delevel` with standard Index with name set (GH #393)
102103

103104
**Bug fixes**
104105

@@ -137,6 +138,7 @@ pandas 0.5.1
137138
- Fixed repr exception when Series name is a tuple
138139
- Always return DateRange from `asfreq` (GH #390)
139140
- Pass level names to `swaplavel` (GH #379)
141+
- Don't lose index names in `MultiIndex.droplevel` (GH #394)
140142

141143
Thanks
142144
------

pandas/core/frame.py

+12-13
Original file line numberDiff line numberDiff line change
@@ -2053,21 +2053,20 @@ def delevel(self):
20532053
-------
20542054
deleveled : DataFrame
20552055
"""
2056-
if not isinstance(self.index, MultiIndex):
2057-
raise Exception('this DataFrame does not have a multi-level index')
2058-
20592056
new_obj = self.copy()
2060-
names = self.index.names
2061-
2062-
zipped = zip(self.index.levels, self.index.labels)
2063-
for i, (lev, lab) in reversed(list(enumerate(zipped))):
2064-
col_name = names[i]
2065-
if col_name is None:
2066-
col_name = 'level_%d' % i
2067-
new_obj.insert(0, col_name, np.asarray(lev).take(lab))
2068-
2057+
if isinstance(self.index, MultiIndex):
2058+
names = self.index.names
2059+
zipped = zip(self.index.levels, self.index.labels)
2060+
for i, (lev, lab) in reversed(list(enumerate(zipped))):
2061+
col_name = names[i]
2062+
if col_name is None:
2063+
col_name = 'level_%d' % i
2064+
new_obj.insert(0, col_name, np.asarray(lev).take(lab))
2065+
else:
2066+
if self.index.name is None:
2067+
raise Exception('Must have name set')
2068+
new_obj.insert(0, self.index.name, self.index.values)
20692069
new_obj.index = np.arange(len(new_obj))
2070-
20712070
return new_obj
20722071

20732072
#----------------------------------------------------------------------

pandas/tests/test_frame.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -3313,15 +3313,27 @@ def test_stack_unstack(self):
33133313
def test_delevel(self):
33143314
stacked = self.frame.stack()[::2]
33153315
stacked = DataFrame({'foo' : stacked, 'bar' : stacked})
3316-
deleveled = stacked.delevel()
33173316

3317+
names = ['first', 'second']
3318+
stacked.index.names = names
3319+
deleveled = stacked.delevel()
33183320
for i, (lev, lab) in enumerate(zip(stacked.index.levels,
33193321
stacked.index.labels)):
33203322
values = lev.take(lab)
3321-
assert_almost_equal(values, deleveled['level_%d' % i])
3323+
name = names[i]
3324+
assert_almost_equal(values, deleveled[name])
33223325

3326+
# exception if no name
33233327
self.assertRaises(Exception, self.frame.delevel)
33243328

3329+
# but this is ok
3330+
self.frame.index.name = 'index'
3331+
deleveled = self.frame.delevel()
3332+
self.assert_(np.array_equal(deleveled['index'],
3333+
self.frame.index.values))
3334+
self.assert_(np.array_equal(deleveled.index,
3335+
np.arange(len(deleveled))))
3336+
33253337
#----------------------------------------------------------------------
33263338
# Tests to cope with refactored internals
33273339

0 commit comments

Comments
 (0)