Skip to content

Commit 3625933

Browse files
committed
ENH: add reorder_levels to Series and add unit testing per #534
1 parent ba9de8a commit 3625933

File tree

5 files changed

+38
-1
lines changed

5 files changed

+38
-1
lines changed

RELEASE.rst

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pandas 0.6.2
4040
- Handle differently-indexed output values in ``DataFrame.apply`` (GH #498)
4141
- Can pass list of dicts (e.g., a list of shallow JSON objects) to DataFrame
4242
constructor (GH #526)
43+
- Add `reorder_levels` method to Series and DataFrame (PR #534)
4344

4445
**Improvements to existing features**
4546

pandas/core/frame.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1809,7 +1809,7 @@ def reorder_levels(self, order, axis=0):
18091809
-------
18101810
type of caller (new object)
18111811
"""
1812-
if not isinstance(self._get_axis(axis), MultiIndex):
1812+
if not isinstance(self._get_axis(axis), MultiIndex): # pragma: no cover
18131813
raise Exception('Can only reorder levels on a hierarchical axis.')
18141814

18151815
result = self.copy()

pandas/core/index.py

+1
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,7 @@ def reorder_levels(self, order):
12391239
Parameters
12401240
----------
12411241
"""
1242+
order = [self._get_level_number(i) for i in order]
12421243
try:
12431244
assert(set(order) == set(range(self.nlevels)))
12441245
except AssertionError:

pandas/core/series.py

+22
Original file line numberDiff line numberDiff line change
@@ -1338,6 +1338,28 @@ def swaplevel(self, i, j, copy=True):
13381338
new_index = self.index.swaplevel(i, j)
13391339
return Series(self.values, index=new_index, copy=copy, name=self.name)
13401340

1341+
def reorder_levels(self, order):
1342+
"""
1343+
Rearrange index levels using input order. May not drop or duplicate
1344+
levels
1345+
1346+
Parameters
1347+
----------
1348+
order: list of int representing new level order.
1349+
(reference level by number not by key)
1350+
axis: where to reorder levels
1351+
1352+
Returns
1353+
-------
1354+
type of caller (new object)
1355+
"""
1356+
if not isinstance(self.index, MultiIndex): # pragma: no cover
1357+
raise Exception('Can only reorder levels on a hierarchical axis.')
1358+
1359+
result = self.copy()
1360+
result.index = result.index.reorder_levels(order)
1361+
return result
1362+
13411363
def unstack(self, level=-1):
13421364
"""
13431365
Unstack, a.k.a. pivot, Series with MultiIndex to produce DataFrame

pandas/tests/test_multilevel.py

+13
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,19 @@ def test_swaplevel_panel(self):
526526
expected.major_axis = expected.major_axis.swaplevel(0, 1)
527527
tm.assert_panel_equal(result, expected)
528528

529+
def test_reorder_levels(self):
530+
result = self.ymd.reorder_levels(['month', 'day', 'year'])
531+
expected = self.ymd.swaplevel(0, 1).swaplevel(1, 2)
532+
assert_frame_equal(result, expected)
533+
534+
result = self.ymd['A'].reorder_levels(['month', 'day', 'year'])
535+
expected = self.ymd['A'].swaplevel(0, 1).swaplevel(1, 2)
536+
assert_series_equal(result, expected)
537+
538+
result = self.ymd.T.reorder_levels(['month', 'day', 'year'], axis=1)
539+
expected = self.ymd.T.swaplevel(0, 1, axis=1).swaplevel(1, 2, axis=1)
540+
assert_frame_equal(result, expected)
541+
529542
def test_insert_index(self):
530543
df = self.ymd[:5].T
531544
df[2000, 1, 10] = df[2000, 1, 7]

0 commit comments

Comments
 (0)