From e6e33c40e081f4fcd2a6ef7c4b64394bba35bdaf Mon Sep 17 00:00:00 2001 From: iabhi4 Date: Thu, 29 May 2025 17:55:10 -0700 Subject: [PATCH] BUG: Allow sorting by column named None in DataFrame.sort_values (GH#61512) --- doc/source/whatsnew/v3.0.0.rst | 1 + pandas/core/generic.py | 6 +----- pandas/tests/frame/methods/test_sort_values.py | 7 +++++++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 099e5bc48353a..cea143c08bd2f 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -886,6 +886,7 @@ Other - Bug in :meth:`DataFrame.query` which raised an exception when querying integer column names using backticks. (:issue:`60494`) - Bug in :meth:`DataFrame.shift` where passing a ``freq`` on a DataFrame with no columns did not shift the index correctly. (:issue:`60102`) - Bug in :meth:`DataFrame.sort_index` when passing ``axis="columns"`` and ``ignore_index=True`` and ``ascending=False`` not returning a :class:`RangeIndex` columns (:issue:`57293`) +- Bug in :meth:`DataFrame.sort_values` where sorting by a column explicitly named ``None`` raised a ``KeyError`` instead of sorting by the column as expected. (:issue:`61512`) - Bug in :meth:`DataFrame.transform` that was returning the wrong order unless the index was monotonically increasing. (:issue:`57069`) - Bug in :meth:`DataFrame.where` where using a non-bool type array in the function would return a ``ValueError`` instead of a ``TypeError`` (:issue:`56330`) - Bug in :meth:`Index.sort_values` when passing a key function that turns values into tuples, e.g. ``key=natsort.natsort_key``, would raise ``TypeError`` (:issue:`56081`) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 13585d7de6beb..8aae4609b1833 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1645,11 +1645,7 @@ def _is_label_reference(self, key: Level, axis: Axis = 0) -> bool: axis_int = self._get_axis_number(axis) other_axes = (ax for ax in range(self._AXIS_LEN) if ax != axis_int) - return ( - key is not None - and is_hashable(key) - and any(key in self.axes[ax] for ax in other_axes) - ) + return is_hashable(key) and any(key in self.axes[ax] for ax in other_axes) @final def _is_label_or_level_reference(self, key: Level, axis: AxisInt = 0) -> bool: diff --git a/pandas/tests/frame/methods/test_sort_values.py b/pandas/tests/frame/methods/test_sort_values.py index e728526519e9d..9a628c2ee9f73 100644 --- a/pandas/tests/frame/methods/test_sort_values.py +++ b/pandas/tests/frame/methods/test_sort_values.py @@ -630,6 +630,13 @@ def test_sort_values_no_op_reset_index(self): expected = DataFrame({"A": [10, 20], "B": [1, 5]}) tm.assert_frame_equal(result, expected) + def test_sort_by_column_named_none(self): + # GH#61512 + df = DataFrame([[3, 1], [2, 2]], columns=[None, "C1"]) + result = df.sort_values(by=None) + expected = DataFrame([[2, 2], [3, 1]], columns=[None, "C1"], index=[1, 0]) + tm.assert_frame_equal(result, expected) + class TestDataFrameSortKey: # test key sorting (issue 27237) def test_sort_values_inplace_key(self, sort_by_key):