Skip to content

Commit ed324e8

Browse files
brandon-rhodesjreback
authored andcommitted
Add defaults to swaplevel() parameters i and j
Closes #12934 feature request. Author: Brandon Rhodes <[email protected]> Closes #12943 from brandon-rhodes/master and squashes the following commits: c6fbb3e [Brandon Rhodes] Add default values to swaplevel() i, j parameters
1 parent 5688d27 commit ed324e8

File tree

7 files changed

+57
-18
lines changed

7 files changed

+57
-18
lines changed

doc/source/whatsnew/v0.18.1.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ v0.18.1 (April ??, 2016)
44
------------------------
55

66
This is a minor bug-fix release from 0.18.0 and includes a large number of
7-
bug fixes along several new features, enhancements, and performance improvements.
7+
bug fixes along with several new features, enhancements, and performance improvements.
88
We recommend that all users upgrade to this version.
99

1010
Highlights include:
@@ -131,6 +131,8 @@ These changes conform sparse handling to return the correct types and work to ma
131131

132132
API changes
133133
~~~~~~~~~~~
134+
- ``.swaplevel()`` for ``Series``, ``DataFrame``, ``Panel``, and ``MultiIndex`` now features defaults for its first two parameters ``i`` and ``j`` that swap the two innermost levels of the index. (:issue:`12934`)
135+
134136
- ``.searchsorted()`` for ``Index`` and ``TimedeltaIndex`` now accept a ``sorter`` argument to maintain compatibility with numpy's ``searchsorted`` function (:issue:`12238`)
135137

136138
- ``Period`` and ``PeriodIndex`` now raises ``IncompatibleFrequency`` error which inherits ``ValueError`` rather than raw ``ValueError`` (:issue:`12615`)

pandas/core/frame.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3384,7 +3384,7 @@ def nsmallest(self, n, columns, keep='first'):
33843384
"""
33853385
return self._nsorted(columns, n, 'nsmallest', keep)
33863386

3387-
def swaplevel(self, i, j, axis=0):
3387+
def swaplevel(self, i=-2, j=-1, axis=0):
33883388
"""
33893389
Swap levels i and j in a MultiIndex on a particular axis
33903390
@@ -3396,6 +3396,12 @@ def swaplevel(self, i, j, axis=0):
33963396
Returns
33973397
-------
33983398
swapped : type of caller (new object)
3399+
3400+
.. versionchanged:: 0.18.1
3401+
3402+
The indexes ``i`` and ``j`` are now optional, and default to
3403+
the two innermost levels of the index.
3404+
33993405
"""
34003406
result = self.copy()
34013407

pandas/core/generic.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ def squeeze(self):
522522
except:
523523
return self
524524

525-
def swaplevel(self, i, j, axis=0):
525+
def swaplevel(self, i=-2, j=-1, axis=0):
526526
"""
527527
Swap levels i and j in a MultiIndex on a particular axis
528528
@@ -534,6 +534,12 @@ def swaplevel(self, i, j, axis=0):
534534
Returns
535535
-------
536536
swapped : type of caller (new object)
537+
538+
.. versionchanged:: 0.18.1
539+
540+
The indexes ``i`` and ``j`` are now optional, and default to
541+
the two innermost levels of the index.
542+
537543
"""
538544
axis = self._get_axis_number(axis)
539545
result = self.copy()

pandas/core/series.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1949,7 +1949,7 @@ def sortlevel(self, level=0, ascending=True, sort_remaining=True):
19491949
return self.sort_index(level=level, ascending=ascending,
19501950
sort_remaining=sort_remaining)
19511951

1952-
def swaplevel(self, i, j, copy=True):
1952+
def swaplevel(self, i=-2, j=-1, copy=True):
19531953
"""
19541954
Swap levels i and j in a MultiIndex
19551955
@@ -1961,6 +1961,12 @@ def swaplevel(self, i, j, copy=True):
19611961
Returns
19621962
-------
19631963
swapped : Series
1964+
1965+
.. versionchanged:: 0.18.1
1966+
1967+
The indexes ``i`` and ``j`` are now optional, and default to
1968+
the two innermost levels of the index.
1969+
19641970
"""
19651971
new_index = self.index.swaplevel(i, j)
19661972
return self._constructor(self._values, index=new_index,

pandas/indexes/multi.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1194,7 +1194,7 @@ def droplevel(self, level=0):
11941194
return MultiIndex(levels=new_levels, labels=new_labels,
11951195
names=new_names, verify_integrity=False)
11961196

1197-
def swaplevel(self, i, j):
1197+
def swaplevel(self, i=-2, j=-1):
11981198
"""
11991199
Swap level i with level j. Do not change the ordering of anything
12001200
@@ -1206,6 +1206,12 @@ def swaplevel(self, i, j):
12061206
Returns
12071207
-------
12081208
swapped : MultiIndex
1209+
1210+
.. versionchanged:: 0.18.1
1211+
1212+
The indexes ``i`` and ``j`` are now optional, and default to
1213+
the two innermost levels of the index.
1214+
12091215
"""
12101216
new_levels = list(self.levels)
12111217
new_labels = list(self.labels)

pandas/tests/indexes/test_multi.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,12 +2095,15 @@ def test_partial_string_timestamp_multiindex(self):
20952095
# c 14
20962096

20972097
# partial string matching on a single index
2098-
df_swap = df.swaplevel(0, 1).sort_index()
2099-
just_a = df_swap.loc['a']
2100-
result = just_a.loc['2016-01-01']
2101-
expected = df.loc[idx[:, 'a'], :].iloc[0:2]
2102-
expected.index = expected.index.droplevel(1)
2103-
tm.assert_frame_equal(result, expected)
2098+
for df_swap in (df.swaplevel(),
2099+
df.swaplevel(0),
2100+
df.swaplevel(0, 1)):
2101+
df_swap = df_swap.sort_index()
2102+
just_a = df_swap.loc['a']
2103+
result = just_a.loc['2016-01-01']
2104+
expected = df.loc[idx[:, 'a'], :].iloc[0:2]
2105+
expected.index = expected.index.droplevel(1)
2106+
tm.assert_frame_equal(result, expected)
21042107

21052108
# indexing with IndexSlice
21062109
result = df.loc[idx['2016-01-01':'2016-02-01', :], :]

pandas/tests/test_multilevel.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,15 +1320,23 @@ def test_join(self):
13201320
) # TODO what should join do with names ?
13211321

13221322
def test_swaplevel(self):
1323-
swapped = self.frame['A'].swaplevel(0, 1)
1324-
swapped2 = self.frame['A'].swaplevel('first', 'second')
1323+
swapped = self.frame['A'].swaplevel()
1324+
swapped2 = self.frame['A'].swaplevel(0)
1325+
swapped3 = self.frame['A'].swaplevel(0, 1)
1326+
swapped4 = self.frame['A'].swaplevel('first', 'second')
13251327
self.assertFalse(swapped.index.equals(self.frame.index))
13261328
assert_series_equal(swapped, swapped2)
1329+
assert_series_equal(swapped, swapped3)
1330+
assert_series_equal(swapped, swapped4)
13271331

1328-
back = swapped.swaplevel(0, 1)
1329-
back2 = swapped.swaplevel('second', 'first')
1332+
back = swapped.swaplevel()
1333+
back2 = swapped.swaplevel(0)
1334+
back3 = swapped.swaplevel(0, 1)
1335+
back4 = swapped.swaplevel('second', 'first')
13301336
self.assertTrue(back.index.equals(self.frame.index))
13311337
assert_series_equal(back, back2)
1338+
assert_series_equal(back, back3)
1339+
assert_series_equal(back, back4)
13321340

13331341
ft = self.frame.T
13341342
swapped = ft.swaplevel('first', 'second', axis=1)
@@ -1337,11 +1345,13 @@ def test_swaplevel(self):
13371345

13381346
def test_swaplevel_panel(self):
13391347
panel = Panel({'ItemA': self.frame, 'ItemB': self.frame * 2})
1340-
1341-
result = panel.swaplevel(0, 1, axis='major')
13421348
expected = panel.copy()
13431349
expected.major_axis = expected.major_axis.swaplevel(0, 1)
1344-
tm.assert_panel_equal(result, expected)
1350+
1351+
for result in (panel.swaplevel(axis='major'),
1352+
panel.swaplevel(0, axis='major'),
1353+
panel.swaplevel(0, 1, axis='major')):
1354+
tm.assert_panel_equal(result, expected)
13451355

13461356
def test_reorder_levels(self):
13471357
result = self.ymd.reorder_levels(['month', 'day', 'year'])

0 commit comments

Comments
 (0)