Skip to content

Commit bc09d57

Browse files
Backport PR #57169 on branch 2.2.x (REGR: DataFrame.sort_index not producing stable sort) (#57180)
Backport PR #57169: REGR: DataFrame.sort_index not producing stable sort Co-authored-by: Luke Manley <[email protected]>
1 parent 59e6c80 commit bc09d57

File tree

3 files changed

+29
-7
lines changed

3 files changed

+29
-7
lines changed

doc/source/whatsnew/v2.2.1.rst

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Fixed regressions
1818
- Fixed regression in :func:`merge_ordered` raising ``TypeError`` for ``fill_method="ffill"`` and ``how="left"`` (:issue:`57010`)
1919
- Fixed regression in :func:`wide_to_long` raising an ``AttributeError`` for string columns (:issue:`57066`)
2020
- Fixed regression in :meth:`DataFrame.loc` raising ``IndexError`` for non-unique, masked dtype indexes where result has more than 10,000 rows (:issue:`57027`)
21+
- Fixed regression in :meth:`DataFrame.sort_index` not producing a stable sort for a index with duplicates (:issue:`57151`)
2122
- Fixed regression in :meth:`DataFrame.to_dict` with ``orient='list'`` and datetime or timedelta types returning integers (:issue:`54824`)
2223
- Fixed regression in :meth:`DataFrameGroupBy.idxmin`, :meth:`DataFrameGroupBy.idxmax`, :meth:`SeriesGroupBy.idxmin`, :meth:`SeriesGroupBy.idxmax` ignoring the ``skipna`` argument (:issue:`57040`)
2324
- Fixed regression in :meth:`DataFrameGroupBy.idxmin`, :meth:`DataFrameGroupBy.idxmax`, :meth:`SeriesGroupBy.idxmin`, :meth:`SeriesGroupBy.idxmax` where values containing the minimum or maximum value for the dtype could produce incorrect results (:issue:`57040`)

pandas/core/indexes/base.py

+4-7
Original file line numberDiff line numberDiff line change
@@ -5914,17 +5914,14 @@ def sort_values(
59145914
(Index([1000, 100, 10, 1], dtype='int64'), array([3, 1, 0, 2]))
59155915
"""
59165916
if key is None and (
5917-
self.is_monotonic_increasing or self.is_monotonic_decreasing
5917+
(ascending and self.is_monotonic_increasing)
5918+
or (not ascending and self.is_monotonic_decreasing)
59185919
):
5919-
reverse = ascending != self.is_monotonic_increasing
5920-
sorted_index = self[::-1] if reverse else self.copy()
59215920
if return_indexer:
59225921
indexer = np.arange(len(self), dtype=np.intp)
5923-
if reverse:
5924-
indexer = indexer[::-1]
5925-
return sorted_index, indexer
5922+
return self.copy(), indexer
59265923
else:
5927-
return sorted_index
5924+
return self.copy()
59285925

59295926
# GH 35584. Sort missing values according to na_position kwarg
59305927
# ignore na_position for MultiIndex

pandas/tests/frame/methods/test_sort_index.py

+24
Original file line numberDiff line numberDiff line change
@@ -1002,3 +1002,27 @@ def test_axis_columns_ignore_index():
10021002
result = df.sort_index(axis="columns", ignore_index=True)
10031003
expected = DataFrame([[2, 1]])
10041004
tm.assert_frame_equal(result, expected)
1005+
1006+
1007+
def test_sort_index_stable_sort():
1008+
# GH 57151
1009+
df = DataFrame(
1010+
data=[
1011+
(Timestamp("2024-01-30 13:00:00"), 13.0),
1012+
(Timestamp("2024-01-30 13:00:00"), 13.1),
1013+
(Timestamp("2024-01-30 12:00:00"), 12.0),
1014+
(Timestamp("2024-01-30 12:00:00"), 12.1),
1015+
],
1016+
columns=["dt", "value"],
1017+
).set_index(["dt"])
1018+
result = df.sort_index(level="dt", kind="stable")
1019+
expected = DataFrame(
1020+
data=[
1021+
(Timestamp("2024-01-30 12:00:00"), 12.0),
1022+
(Timestamp("2024-01-30 12:00:00"), 12.1),
1023+
(Timestamp("2024-01-30 13:00:00"), 13.0),
1024+
(Timestamp("2024-01-30 13:00:00"), 13.1),
1025+
],
1026+
columns=["dt", "value"],
1027+
).set_index(["dt"])
1028+
tm.assert_frame_equal(result, expected)

0 commit comments

Comments
 (0)