From fc5fe33d0a5851af1905d387cdea9e8495ac68b7 Mon Sep 17 00:00:00 2001 From: Deadlica Date: Sun, 3 Mar 2024 17:50:54 +0100 Subject: [PATCH 1/2] #48188 FIX: iloc works with namedtuple - unit test for added for test_iloc.py that verifies that all four uses of iloc given in the reproducible example now works --- pandas/core/indexing.py | 3 +++ pandas/tests/indexing/test_iloc.py | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index c7a938dbc4449..9649eb87009c4 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1738,6 +1738,9 @@ def _getitem_axis(self, key, axis: AxisInt): self._validate_key(key, axis) return self._getbool_axis(key, axis=axis) + if type(key) is tuple or (hasattr(key, "_fields") and isinstance(key, type(key))): + return self.__getitem__(tuple(key)) + # a list of integers elif is_list_like_indexer(key): return self._get_list_axis(key, axis=axis) diff --git a/pandas/tests/indexing/test_iloc.py b/pandas/tests/indexing/test_iloc.py index 8650a1afb383d..260bb22c0bab2 100644 --- a/pandas/tests/indexing/test_iloc.py +++ b/pandas/tests/indexing/test_iloc.py @@ -1449,3 +1449,20 @@ def test_iloc_nullable_int64_size_1_nan(self): result.loc[:, "b"] = result.loc[:, "b"].astype("Int64") expected = DataFrame({"a": ["test"], "b": array([NA], dtype="Int64")}) tm.assert_frame_equal(result, expected) + + def test_iloc_with_namedtuple(self): + df = DataFrame(np.arange(120).reshape(6, -1)) + + output1 = df.iloc[1, 2] + output2 = df.iloc[(1, 2)] + + from collections import namedtuple + + indexer_tuple = namedtuple("Indexer", ["x", "y"]) + + output3 = df.iloc[tuple(indexer_tuple(x=1, y=2))] + output4 = df.iloc[indexer_tuple(x=1, y=2)] + tm.assert_equal(output1, output2) + tm.assert_equal(output3, output4) + tm.assert_equal(output1, output3) + From 2cee8789623752cf01afe5aa0b2454de2f3f6806 Mon Sep 17 00:00:00 2001 From: Deadlica Date: Sun, 3 Mar 2024 18:38:40 +0100 Subject: [PATCH 2/2] #48188 FIX: previous commit broke old else if logic --- pandas/core/indexing.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 9649eb87009c4..356eaf74c759f 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1734,13 +1734,13 @@ def _getitem_axis(self, key, axis: AxisInt): if isinstance(key, list): key = np.asarray(key) + if type(key) is tuple or (hasattr(key, "_fields") and isinstance(key, type(key))): + return self.__getitem__(tuple(key)) + if com.is_bool_indexer(key): self._validate_key(key, axis) return self._getbool_axis(key, axis=axis) - if type(key) is tuple or (hasattr(key, "_fields") and isinstance(key, type(key))): - return self.__getitem__(tuple(key)) - # a list of integers elif is_list_like_indexer(key): return self._get_list_axis(key, axis=axis)