Skip to content

Commit b537eab

Browse files
Backport PR #48246 on branch 1.4.x (REGR: iloc not possible for sparse DataFrame) (#48310)
Backport PR #48246: REGR: iloc not possible for sparse DataFrame
1 parent bc82815 commit b537eab

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

doc/source/whatsnew/v1.4.4.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Fixed regressions
3333
- Fixed regression in :meth:`DatetimeIndex.intersection` when the :class:`DatetimeIndex` has dates crossing daylight savings time (:issue:`46702`)
3434
- Fixed regression in :func:`merge` throwing an error when passing a :class:`Series` with a multi-level name (:issue:`47946`)
3535
- Fixed regression in :meth:`DataFrame.eval` creating a copy when updating inplace (:issue:`47449`)
36-
-
36+
- Fixed regression where getting a row using :meth:`DataFrame.iloc` with :class:`SparseDtype` would raise (:issue:`46406`)
3737

3838
.. ---------------------------------------------------------------------------
3939

pandas/core/internals/managers.py

+15-2
Original file line numberDiff line numberDiff line change
@@ -995,11 +995,20 @@ def fast_xs(self, loc: int) -> ArrayLike:
995995
dtype = interleaved_dtype([blk.dtype for blk in self.blocks])
996996

997997
n = len(self)
998-
if isinstance(dtype, ExtensionDtype):
998+
999+
# GH#46406
1000+
immutable_ea = isinstance(dtype, SparseDtype)
1001+
1002+
if isinstance(dtype, ExtensionDtype) and not immutable_ea:
9991003
cls = dtype.construct_array_type()
10001004
result = cls._empty((n,), dtype=dtype)
10011005
else:
1002-
result = np.empty(n, dtype=dtype)
1006+
# error: Argument "dtype" to "empty" has incompatible type
1007+
# "Union[Type[object], dtype[Any], ExtensionDtype, None]"; expected
1008+
# "None"
1009+
result = np.empty(
1010+
n, dtype=object if immutable_ea else dtype # type: ignore[arg-type]
1011+
)
10031012
result = ensure_wrapped_if_datetimelike(result)
10041013

10051014
for blk in self.blocks:
@@ -1008,6 +1017,10 @@ def fast_xs(self, loc: int) -> ArrayLike:
10081017
for i, rl in enumerate(blk.mgr_locs):
10091018
result[rl] = blk.iget((i, loc))
10101019

1020+
if immutable_ea:
1021+
dtype = cast(ExtensionDtype, dtype)
1022+
result = dtype.construct_array_type()._from_sequence(result, dtype=dtype)
1023+
10111024
return result
10121025

10131026
def iget(self, i: int) -> SingleBlockManager:

pandas/tests/indexing/test_loc.py

+8
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,14 @@ def test_loc_getitem_sparse_series(self):
12911291
expected = Series([1.0, 0.0], dtype=SparseDtype("float64", 0.0))
12921292
tm.assert_series_equal(result, expected)
12931293

1294+
@pytest.mark.parametrize("indexer", ["loc", "iloc"])
1295+
def test_getitem_single_row_sparse_df(self, indexer):
1296+
# GH#46406
1297+
df = DataFrame([[1.0, 0.0, 1.5], [0.0, 2.0, 0.0]], dtype=SparseDtype(float))
1298+
result = getattr(df, indexer)[0]
1299+
expected = Series([1.0, 0.0, 1.5], dtype=SparseDtype(float), name=0)
1300+
tm.assert_series_equal(result, expected)
1301+
12941302
@pytest.mark.parametrize("key_type", [iter, np.array, Series, Index])
12951303
def test_loc_getitem_iterable(self, float_frame, key_type):
12961304
idx = key_type(["A", "B", "C"])

0 commit comments

Comments
 (0)