Skip to content

Commit 0490e1b

Browse files
BUG: Fix return type of loc/iloc (#61054)
* Fix loc dtype Co-authored-by: Parthi <[email protected]> * Modify test_loc_setitem_frame_mixed_labels accordingly * Add test for the linked issue * Fix test_loc_dtype * Fix dtype inference * Reverse tuple to avoid unintended dtype inference * Reverse axis order * Reverse indexing order * Explicitly assign the expected result * Add whatsnew --------- Co-authored-by: Parthi <[email protected]>
1 parent eaa6aaf commit 0490e1b

File tree

4 files changed

+16
-5
lines changed

4 files changed

+16
-5
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,7 @@ Indexing
748748
- Bug in :meth:`DataFrame.__getitem__` returning modified columns when called with ``slice`` in Python 3.12 (:issue:`57500`)
749749
- Bug in :meth:`DataFrame.__getitem__` when slicing a :class:`DataFrame` with many rows raised an ``OverflowError`` (:issue:`59531`)
750750
- Bug in :meth:`DataFrame.from_records` throwing a ``ValueError`` when passed an empty list in ``index`` (:issue:`58594`)
751+
- Bug in :meth:`DataFrame.loc` and :meth:`DataFrame.iloc` returning incorrect dtype when selecting from a :class:`DataFrame` with mixed data types. (:issue:`60600`)
751752
- Bug in :meth:`DataFrame.loc` with inconsistent behavior of loc-set with 2 given indexes to Series (:issue:`59933`)
752753
- Bug in :meth:`Index.get_indexer` and similar methods when ``NaN`` is located at or after position 128 (:issue:`58924`)
753754
- Bug in :meth:`MultiIndex.insert` when a new value inserted to a datetime-like level gets cast to ``NaT`` and fails indexing (:issue:`60388`)

pandas/core/indexing.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,8 +1066,10 @@ def _getitem_lowerdim(self, tup: tuple):
10661066

10671067
tup = self._validate_key_length(tup)
10681068

1069-
for i, key in enumerate(tup):
1070-
if is_label_like(key):
1069+
# Reverse tuple so that we are indexing along columns before rows
1070+
# and avoid unintended dtype inference. # GH60600
1071+
for i, key in zip(range(len(tup) - 1, -1, -1), reversed(tup)):
1072+
if is_label_like(key) or is_list_like(key):
10711073
# We don't need to check for tuples here because those are
10721074
# caught by the _is_nested_tuple_indexer check above.
10731075
section = self._getitem_axis(key, axis=i)

pandas/tests/indexing/multiindex/test_loc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ def test_missing_keys_raises_keyerror(self):
757757
df = DataFrame(np.arange(12).reshape(4, 3), columns=["A", "B", "C"])
758758
df2 = df.set_index(["A", "B"])
759759

760-
with pytest.raises(KeyError, match="1"):
760+
with pytest.raises(KeyError, match="6"):
761761
df2.loc[(1, 6)]
762762

763763
def test_missing_key_raises_keyerror2(self):

pandas/tests/indexing/test_loc.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ def test_not_change_nan_loc(series, new_series, expected_ser):
6060
tm.assert_frame_equal(df.notna(), ~expected)
6161

6262

63+
def test_loc_dtype():
64+
# GH 60600
65+
df = DataFrame([["a", 1.0, 2.0], ["b", 3.0, 4.0]])
66+
result = df.loc[0, [1, 2]]
67+
expected = Series([1.0, 2.0], index=[1, 2], dtype=float, name=0)
68+
tm.assert_series_equal(result, expected)
69+
70+
6371
class TestLoc:
6472
def test_none_values_on_string_columns(self, using_infer_string):
6573
# Issue #32218
@@ -441,7 +449,7 @@ def test_loc_to_fail(self):
441449

442450
msg = (
443451
rf"\"None of \[Index\(\[1, 2\], dtype='{np.dtype(int)}'\)\] are "
444-
r"in the \[index\]\""
452+
r"in the \[columns\]\""
445453
)
446454
with pytest.raises(KeyError, match=msg):
447455
df.loc[[1, 2], [1, 2]]
@@ -807,7 +815,7 @@ def test_loc_setitem_frame_mixed_labels(self):
807815

808816
result = df.loc[0, [1, 2]]
809817
expected = Series(
810-
[1, 3], index=Index([1, 2], dtype=object), dtype=object, name=0
818+
[1, 3], index=Index([1, 2], dtype=object), dtype="int64", name=0
811819
)
812820
tm.assert_series_equal(result, expected)
813821

0 commit comments

Comments
 (0)