Skip to content

Commit 2caee96

Browse files
committed
BUG: sort_index throws IndexError for some permutations (#26053)
- (lev - i) will be out of bounds for pop if the first index dim is to be sorted last
1 parent e02ec8f commit 2caee96

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

pandas/core/indexes/multi.py

+16-2
Original file line numberDiff line numberDiff line change
@@ -2085,8 +2085,22 @@ def sortlevel(self, level=0, ascending=True, sort_remaining=True):
20852085
shape = list(self.levshape)
20862086

20872087
# partition codes and shape
2088-
primary = tuple(codes.pop(lev - i) for i, lev in enumerate(level))
2089-
primshp = tuple(shape.pop(lev - i) for i, lev in enumerate(level))
2088+
primary = []
2089+
primshp = []
2090+
2091+
# Add the required codes and shape
2092+
for lev in level:
2093+
primary.append(codes[lev])
2094+
primshp.append(shape[lev])
2095+
2096+
primary = tuple(primary)
2097+
primshp = tuple(primshp)
2098+
2099+
# Reverse sorted to retain the order of
2100+
# smaller indices that needs to be removed
2101+
for lev in sorted(level, reverse=True):
2102+
codes.pop(lev)
2103+
shape.pop(lev)
20902104

20912105
if sort_remaining:
20922106
primary += primary + tuple(codes)

pandas/tests/frame/test_sorting.py

+10
Original file line numberDiff line numberDiff line change
@@ -496,12 +496,22 @@ def test_sort_index_duplicates(self):
496496
def test_sort_index_level(self):
497497
mi = MultiIndex.from_tuples([[1, 1, 3], [1, 1, 1]], names=list('ABC'))
498498
df = DataFrame([[1, 2], [3, 4]], mi)
499+
499500
res = df.sort_index(level='A', sort_remaining=False)
500501
assert_frame_equal(df, res)
501502

502503
res = df.sort_index(level=['A', 'B'], sort_remaining=False)
503504
assert_frame_equal(df, res)
504505

506+
res = df.sort_index(level=['C', 'B', 'A'])
507+
assert_frame_equal(df.iloc[[1, 0]], res)
508+
509+
res = df.sort_index(level=['B', 'C', 'A'])
510+
assert_frame_equal(df.iloc[[1, 0]], res)
511+
512+
res = df.sort_index(level=['C', 'A'])
513+
assert_frame_equal(df.iloc[[1, 0]], res)
514+
505515
def test_sort_index_categorical_index(self):
506516

507517
df = (DataFrame({'A': np.arange(6, dtype='int64'),

0 commit comments

Comments
 (0)