Skip to content

Commit fd83502

Browse files
committed
BUG: support for "level=" when reset_index() is called with a flat Index
closes #16263
1 parent e513430 commit fd83502

File tree

3 files changed

+40
-10
lines changed

3 files changed

+40
-10
lines changed

doc/source/whatsnew/v0.20.2.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Conversion
4242
Indexing
4343
^^^^^^^^
4444

45-
45+
- Bug in ``DataFrame.reset_index(level=)`` with flat index (:issue:`16263`)
4646

4747

4848
I/O

pandas/core/frame.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -3012,12 +3012,12 @@ def _maybe_casted_values(index, labels=None):
30123012
return values
30133013

30143014
new_index = _default_index(len(new_obj))
3015-
if isinstance(self.index, MultiIndex):
3016-
if level is not None:
3017-
if not isinstance(level, (tuple, list)):
3018-
level = [level]
3019-
level = [self.index._get_level_number(lev) for lev in level]
3020-
if len(level) < len(self.index.levels):
3015+
if level is not None:
3016+
if not isinstance(level, (tuple, list)):
3017+
level = [level]
3018+
level = [self.index._get_level_number(lev) for lev in level]
3019+
if isinstance(self.index, MultiIndex):
3020+
if len(level) < self.index.nlevels:
30213021
new_index = self.index.droplevel(level)
30223022

30233023
if not drop:
@@ -3033,6 +3033,8 @@ def _maybe_casted_values(index, labels=None):
30333033

30343034
multi_col = isinstance(self.columns, MultiIndex)
30353035
for i, (lev, lab) in reversed(list(enumerate(to_insert))):
3036+
if not (level is None or i in level):
3037+
continue
30363038
name = names[i]
30373039
if multi_col:
30383040
col_name = (list(name) if isinstance(name, tuple)
@@ -3049,11 +3051,9 @@ def _maybe_casted_values(index, labels=None):
30493051
missing = self.columns.nlevels - len(name_lst)
30503052
name_lst += [col_fill] * missing
30513053
name = tuple(name_lst)
3052-
30533054
# to ndarray and maybe infer different dtype
30543055
level_values = _maybe_casted_values(lev, lab)
3055-
if level is None or i in level:
3056-
new_obj.insert(0, name, level_values)
3056+
new_obj.insert(0, name, level_values)
30573057

30583058
new_obj.index = new_index
30593059
if not inplace:

pandas/tests/frame/test_alter_axes.py

+30
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,36 @@ def test_reset_index(self):
641641
xp = xp.set_index(['B'], append=True)
642642
assert_frame_equal(rs, xp, check_names=False)
643643

644+
def test_reset_index_level(self):
645+
df = pd.DataFrame([[1, 2, 3, 4], [5, 6, 7, 8]],
646+
columns=['A', 'B', 'C', 'D'])
647+
648+
# With MultiIndex
649+
for levels in ['A', 'B'], [0, 1]:
650+
result = df.set_index(['A', 'B']).reset_index(level=levels[0])
651+
tm.assert_frame_equal(result, df.set_index('B'))
652+
653+
result = df.set_index(['A', 'B']).reset_index(level=levels[:1])
654+
tm.assert_frame_equal(result, df.set_index('B'))
655+
656+
result = df.set_index(['A', 'B']).reset_index(level=levels)
657+
tm.assert_frame_equal(result, df)
658+
659+
# With flat Index (GH 16263)
660+
for level in 'A', 0:
661+
result = df.set_index('A').reset_index(level=level)
662+
tm.assert_frame_equal(result, df)
663+
664+
result = df.set_index('A').reset_index(level=[level])
665+
tm.assert_frame_equal(result, df)
666+
667+
# Missing levels - for both MultiIndex and flat Index:
668+
for idx_lev in ['A', 'B'], ['A']:
669+
with tm.assert_raises_regex(KeyError, 'Level E '):
670+
df.set_index(idx_lev).reset_index(level=['A', 'E'])
671+
with tm.assert_raises_regex(IndexError, 'Too many levels'):
672+
df.set_index(idx_lev).reset_index(level=[0, 1, 2])
673+
644674
def test_reset_index_right_dtype(self):
645675
time = np.arange(0.0, 10, np.sqrt(2) / 2)
646676
s1 = Series((9.81 * time ** 2) / 2,

0 commit comments

Comments
 (0)