Skip to content

Commit 26e7c0f

Browse files
authored
BUG: 1D slices over extension types turn into N-dimensional slices over ExtensionArrays (#42787)
1 parent 13560bb commit 26e7c0f

File tree

3 files changed

+24
-6
lines changed

3 files changed

+24
-6
lines changed

doc/source/whatsnew/v1.3.2.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Fixed regressions
3030

3131
Bug fixes
3232
~~~~~~~~~
33-
-
33+
- 1D slices over extension types turn into N-dimensional slices over ExtensionArrays (:issue:`42430`)
3434
-
3535

3636
.. ---------------------------------------------------------------------------

pandas/core/internals/blocks.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -1552,12 +1552,10 @@ def _slice(self, slicer):
15521552
def getitem_block_index(self, slicer: slice) -> ExtensionBlock:
15531553
"""
15541554
Perform __getitem__-like specialized to slicing along index.
1555-
1556-
Assumes self.ndim == 2
15571555
"""
1558-
# error: Invalid index type "Tuple[ellipsis, slice]" for
1559-
# "Union[ndarray, ExtensionArray]"; expected type "Union[int, slice, ndarray]"
1560-
new_values = self.values[..., slicer] # type: ignore[index]
1556+
# GH#42787 in principle this is equivalent to values[..., slicer], but we don't
1557+
# require subclasses of ExtensionArray to support that form (for now).
1558+
new_values = self.values[slicer]
15611559
return type(self)(new_values, self._mgr_locs, ndim=self.ndim)
15621560

15631561
def fillna(

pandas/tests/extension/base/getitem.py

+20
Original file line numberDiff line numberDiff line change
@@ -425,3 +425,23 @@ def test_item(self, data):
425425

426426
with pytest.raises(ValueError, match=msg):
427427
s.item()
428+
429+
def test_ellipsis_index(self):
430+
# GH42430 1D slices over extension types turn into N-dimensional slices over
431+
# ExtensionArrays
432+
class CapturingStringArray(pd.arrays.StringArray):
433+
"""Extend StringArray to capture arguments to __getitem__"""
434+
435+
def __getitem__(self, item):
436+
self.last_item_arg = item
437+
return super().__getitem__(item)
438+
439+
df = pd.DataFrame(
440+
{"col1": CapturingStringArray(np.array(["hello", "world"], dtype=object))}
441+
)
442+
_ = df.iloc[:1]
443+
444+
# String comparison because there's no native way to compare slices.
445+
# Before the fix for GH42430, last_item_arg would get set to the 2D slice
446+
# (Ellipsis, slice(None, 1, None))
447+
self.assert_equal(str(df["col1"].array.last_item_arg), "slice(None, 1, None)")

0 commit comments

Comments
 (0)