Skip to content

Commit a089991

Browse files
committed
fix it
1 parent 1b7cf04 commit a089991

File tree

4 files changed

+23
-7
lines changed

4 files changed

+23
-7
lines changed

doc/source/whatsnew/v1.1.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,7 @@ Sparse
11231123
- Creating a :class:`SparseArray` from timezone-aware dtype will issue a warning before dropping timezone information, instead of doing so silently (:issue:`32501`)
11241124
- Bug in :meth:`arrays.SparseArray.from_spmatrix` wrongly read scipy sparse matrix (:issue:`31991`)
11251125
- Bug in :meth:`Series.sum` with ``SparseArray`` raises ``TypeError`` (:issue:`25777`)
1126+
- Bug where :class:`DataFrame` containing :class:`SparseArray` filled with ``NaN`` when indexed by a list-like (:issue:`27781`, :issue:`29563`)
11261127
- The repr of :class:`SparseDtype` now includes the repr of its ``fill_value`` attribute. Previously it used ``fill_value``'s string representation (:issue:`34352`)
11271128
- Bug where empty :class:`DataFrame` could not be cast to :class:`SparseDtype` (:issue:`33113`)
11281129
- Bug in :meth:`arrays.SparseArray` was returning the incorrect type when indexing a sparse dataframe with an iterable (:issue:`34526`, :issue:`34540`)

pandas/core/arrays/sparse/array.py

+12-7
Original file line numberDiff line numberDiff line change
@@ -862,21 +862,26 @@ def _take_with_fill(self, indices, fill_value=None) -> np.ndarray:
862862
else:
863863
raise IndexError("cannot do a non-empty take from an empty axes.")
864864

865+
# sp_indexer may be -1 for two reasons
866+
# 1.) we took for an index of -1 (new)
867+
# 2.) we took a value that was self.fill_value (old)
865868
sp_indexer = self.sp_index.lookup_array(indices)
869+
new_fill_indices = indices == -1
870+
old_fill_indices = (sp_indexer == -1) & ~new_fill_indices
866871

867-
if self.sp_index.npoints == 0:
872+
if self.sp_index.npoints == 0 and old_fill_indices.all():
873+
# We've looked up all valid points on an all-sparse array.
874+
taken = np.full(
875+
sp_indexer.shape, fill_value=self.fill_value, dtype=self.dtype.subtype
876+
)
877+
878+
elif self.sp_index.npoints == 0:
868879
# Avoid taking from the empty self.sp_values
869880
_dtype = np.result_type(self.dtype.subtype, type(fill_value))
870881
taken = np.full(sp_indexer.shape, fill_value=fill_value, dtype=_dtype)
871882
else:
872883
taken = self.sp_values.take(sp_indexer)
873884

874-
# sp_indexer may be -1 for two reasons
875-
# 1.) we took for an index of -1 (new)
876-
# 2.) we took a value that was self.fill_value (old)
877-
new_fill_indices = indices == -1
878-
old_fill_indices = (sp_indexer == -1) & ~new_fill_indices
879-
880885
# Fill in two steps.
881886
# Old fill values
882887
# New fill values

pandas/tests/arrays/sparse/test_array.py

+5
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,11 @@ def test_take(self):
281281
exp = SparseArray(np.take(self.arr_data, [0, 1, 2]))
282282
tm.assert_sp_array_equal(self.arr.take([0, 1, 2]), exp)
283283

284+
def test_take_all_empty(self):
285+
a = pd.array([0, 0], dtype=pd.SparseDtype("int64"))
286+
result = a.take([0, 1], allow_fill=True, fill_value=np.nan)
287+
tm.assert_sp_array_equal(a, result)
288+
284289
def test_take_fill_value(self):
285290
data = np.array([1, np.nan, 0, 3, 0])
286291
sparse = SparseArray(data, fill_value=0)

pandas/tests/frame/indexing/test_sparse.py

+5
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,8 @@ def test_reindex(self):
6464
index=[0, 2],
6565
)
6666
tm.assert_frame_equal(result, expected)
67+
68+
def test_all_sparse(self):
69+
df = pd.DataFrame({"A": pd.array([0, 0], dtype=pd.SparseDtype("int64"))})
70+
result = df.loc[[0, 1]]
71+
tm.assert_frame_equal(result, df)

0 commit comments

Comments
 (0)