Skip to content

Commit 76747f9

Browse files
authored
BUG: frame.iloc[i] with a single EA column (#45241)
1 parent 345070b commit 76747f9

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

doc/source/whatsnew/v1.5.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ Interval
152152

153153
Indexing
154154
^^^^^^^^
155+
- Bug in :meth:`DataFrame.iloc` where indexing a single row on a :class:`DataFrame` with a single ExtensionDtype column gave a copy instead of a view on the underlying data (:issue:`45241`)
155156
- Bug in :meth:`Series.__setitem__` with a non-integer :class:`Index` when using an integer key to set a value that cannot be set inplace where a ``ValueError`` was raised insead of casting to a common dtype (:issue:`45070`)
156157
-
157158

pandas/core/internals/blocks.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,9 +1515,13 @@ def iget(self, i: int | tuple[int, int] | tuple[slice, int]):
15151515
if not com.is_null_slice(col) and col != 0:
15161516
raise IndexError(f"{self} only contains one item")
15171517
elif isinstance(col, slice):
1518-
if col != slice(None):
1519-
raise NotImplementedError(col)
1520-
return self.values[[loc]]
1518+
# the is_null_slice check above assures that col is slice(None)
1519+
# so what we want is a view on all our columns and row loc
1520+
if loc < 0:
1521+
loc += len(self.values)
1522+
# Note: loc:loc+1 vs [[loc]] makes a difference when called
1523+
# from fast_xs because we want to get a view back.
1524+
return self.values[loc : loc + 1]
15211525
return self.values[loc]
15221526
else:
15231527
if i != 0:

pandas/tests/indexing/test_iloc.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
array,
2525
concat,
2626
date_range,
27+
interval_range,
2728
isna,
2829
)
2930
import pandas._testing as tm
@@ -1177,6 +1178,21 @@ def test_iloc_setitem_2d_ndarray_into_ea_block(self):
11771178
expected = DataFrame({"status": ["a", "a", "c"]}, dtype=df["status"].dtype)
11781179
tm.assert_frame_equal(df, expected)
11791180

1181+
@td.skip_array_manager_not_yet_implemented
1182+
def test_iloc_getitem_int_single_ea_block_view(self):
1183+
# GH#45241
1184+
# TODO: make an extension interface test for this?
1185+
arr = interval_range(1, 10.0)._values
1186+
df = DataFrame(arr)
1187+
1188+
# ser should be a *view* on the the DataFrame data
1189+
ser = df.iloc[2]
1190+
1191+
# if we have a view, then changing arr[2] should also change ser[0]
1192+
assert arr[2] != arr[-1] # otherwise the rest isn't meaningful
1193+
arr[2] = arr[-1]
1194+
assert ser[0] == arr[-1]
1195+
11801196

11811197
class TestILocErrors:
11821198
# NB: this test should work for _any_ Series we can pass as

0 commit comments

Comments
 (0)