Skip to content

Commit 8517c05

Browse files
John David Reaverjreback
John David Reaver
authored andcommitted
BUG: Fix for GH6399, mergesort is unstable when ascending=False
BUG: Fix for GH6399, mergesort is unstable when ascending=False. Update changes
1 parent d1b2fc1 commit 8517c05

File tree

3 files changed

+13
-2
lines changed

3 files changed

+13
-2
lines changed

doc/source/release.rst

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ Improvements to existing features
107107
Bug Fixes
108108
~~~~~~~~~
109109

110+
- Bug in ``pd.DataFrame.sort_index`` where mergesort wasn't stable when ``ascending=False`` (:issue:`6399`)
110111
- Bug in ``pd.tseries.frequencies.to_offset`` when argument has leading zeroes (:issue:`6391`)
111112
- Bug in version string gen. for dev versions with shallow clones / install from tarball (:issue:`6127`)
112113
- Inconsistent tz parsing Timestamp/to_datetime for current year (:issue:`5958`)

pandas/core/frame.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -2612,11 +2612,14 @@ def trans(v):
26122612
if k.ndim == 2:
26132613
raise ValueError('Cannot sort by duplicate column %s'
26142614
% str(by))
2615-
indexer = k.argsort(kind=kind)
26162615
if isinstance(ascending, (tuple, list)):
26172616
ascending = ascending[0]
2617+
2618+
if not ascending:
2619+
k = k[::-1]
2620+
indexer = k.argsort(kind=kind)
26182621
if not ascending:
2619-
indexer = indexer[::-1]
2622+
indexer = indexer.max() - indexer[::-1]
26202623
elif isinstance(labels, MultiIndex):
26212624
indexer = _lexsort_indexer(labels.labels, orders=ascending)
26222625
indexer = com._ensure_platform_int(indexer)

pandas/tests/test_frame.py

+7
Original file line numberDiff line numberDiff line change
@@ -9770,6 +9770,13 @@ def test_frame_column_inplace_sort_exception(self):
97709770
cp = s.copy()
97719771
cp.sort() # it works!
97729772

9773+
def test_stable_descending_sort(self):
9774+
df = DataFrame([[2, 'first'], [2, 'second'], [1, 'a'], [1, 'b']],
9775+
columns=['sort_col', 'order'])
9776+
sorted = df.sort_index(by='sort_col', kind='mergesort',
9777+
ascending=False)
9778+
assert_frame_equal(df, sorted)
9779+
97739780
def test_combine_first(self):
97749781
# disjoint
97759782
head, tail = self.frame[:5], self.frame[5:]

0 commit comments

Comments
 (0)