Skip to content

Commit 5bb694c

Browse files
authored
BUG: np.divmod with Sparse (pandas-dev#44906)
1 parent 86064ff commit 5bb694c

File tree

4 files changed

+18
-32
lines changed

4 files changed

+18
-32
lines changed

pandas/core/arrays/sparse/array.py

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,8 @@ def _sparse_array_op(
181181
ltype = SparseDtype(subtype, left.fill_value)
182182
rtype = SparseDtype(subtype, right.fill_value)
183183

184-
# TODO(GH-23092): pass copy=False. Need to fix astype_nansafe
185-
left = left.astype(ltype)
186-
right = right.astype(rtype)
184+
left = left.astype(ltype, copy=False)
185+
right = right.astype(rtype, copy=False)
187186
dtype = ltype.subtype
188187
else:
189188
dtype = ltype
@@ -233,6 +232,15 @@ def _sparse_array_op(
233232
right.fill_value,
234233
)
235234

235+
if name == "divmod":
236+
# result is a 2-tuple
237+
# error: Incompatible return value type (got "Tuple[SparseArray,
238+
# SparseArray]", expected "SparseArray")
239+
return ( # type: ignore[return-value]
240+
_wrap_result(name, result[0], index, fill[0], dtype=result_dtype),
241+
_wrap_result(name, result[1], index, fill[1], dtype=result_dtype),
242+
)
243+
236244
if result_dtype is None:
237245
result_dtype = result.dtype
238246

@@ -1224,30 +1232,8 @@ def astype(self, dtype: AstypeArg | None = None, copy: bool = True):
12241232
else:
12251233
return self.copy()
12261234
dtype = self.dtype.update_dtype(dtype)
1227-
# error: Item "ExtensionDtype" of "Union[ExtensionDtype, str, dtype[Any],
1228-
# Type[str], Type[float], Type[int], Type[complex], Type[bool], Type[object],
1229-
# None]" has no attribute "_subtype_with_str"
1230-
# error: Item "str" of "Union[ExtensionDtype, str, dtype[Any], Type[str],
1231-
# Type[float], Type[int], Type[complex], Type[bool], Type[object], None]" has no
1232-
# attribute "_subtype_with_str"
1233-
# error: Item "dtype[Any]" of "Union[ExtensionDtype, str, dtype[Any], Type[str],
1234-
# Type[float], Type[int], Type[complex], Type[bool], Type[object], None]" has no
1235-
# attribute "_subtype_with_str"
1236-
# error: Item "ABCMeta" of "Union[ExtensionDtype, str, dtype[Any], Type[str],
1237-
# Type[float], Type[int], Type[complex], Type[bool], Type[object], None]" has no
1238-
# attribute "_subtype_with_str"
1239-
# error: Item "type" of "Union[ExtensionDtype, str, dtype[Any], Type[str],
1240-
# Type[float], Type[int], Type[complex], Type[bool], Type[object], None]" has no
1241-
# attribute "_subtype_with_str"
1242-
# error: Item "None" of "Union[ExtensionDtype, str, dtype[Any], Type[str],
1243-
# Type[float], Type[int], Type[complex], Type[bool], Type[object], None]" has no
1244-
# attribute "_subtype_with_str"
1245-
subtype = pandas_dtype(dtype._subtype_with_str) # type: ignore[union-attr]
1246-
# TODO copy=False is broken for astype_nansafe with int -> float, so cannot
1247-
# passthrough copy keyword: https://github.com/pandas-dev/pandas/issues/34456
1248-
sp_values = astype_nansafe(self.sp_values, subtype, copy=True)
1249-
if sp_values is self.sp_values and copy:
1250-
sp_values = sp_values.copy()
1235+
subtype = pandas_dtype(dtype._subtype_with_str)
1236+
sp_values = astype_nansafe(self.sp_values, subtype, copy=copy)
12511237

12521238
# error: Argument 1 to "_simple_new" of "SparseArray" has incompatible type
12531239
# "ExtensionArray"; expected "ndarray"
@@ -1646,7 +1632,6 @@ def _arith_method(self, other, op):
16461632
else:
16471633
other = np.asarray(other)
16481634
with np.errstate(all="ignore"):
1649-
# TODO: look into _wrap_result
16501635
if len(self) != len(other):
16511636
raise AssertionError(
16521637
f"length mismatch: {len(self)} vs. {len(other)}"

pandas/core/arrays/sparse/dtype.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ def is_dtype(cls, dtype: object) -> bool:
292292
return True
293293
return isinstance(dtype, np.dtype) or dtype == "Sparse"
294294

295-
def update_dtype(self, dtype):
295+
def update_dtype(self, dtype) -> SparseDtype:
296296
"""
297297
Convert the SparseDtype to a new dtype.
298298

pandas/tests/extension/test_sparse.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,10 @@ def test_arith_frame_with_scalar(self, data, all_arithmetic_operators, request):
430430
request.node.add_marker(mark)
431431
super().test_arith_frame_with_scalar(data, all_arithmetic_operators)
432432

433+
def _check_divmod_op(self, ser, op, other, exc=NotImplementedError):
434+
# We implement divmod
435+
super()._check_divmod_op(ser, op, other, exc=None)
436+
433437

434438
class TestComparisonOps(BaseSparseTests, base.BaseComparisonOpsTests):
435439
def _compare_other(self, s, data, comparison_op, other):

pandas/tests/series/test_ufunc.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,6 @@ def test_multiple_output_binary_ufuncs(
177177
# Test that
178178
# the same conditions from binary_ufunc_scalar apply to
179179
# ufuncs with multiple outputs.
180-
if sparse and ufunc is np.divmod:
181-
mark = pytest.mark.xfail(reason="sparse divmod not implemented")
182-
request.node.add_marker(mark)
183180

184181
a1, a2 = arrays_for_binary_ufunc
185182
# work around https://github.com/pandas-dev/pandas/issues/26987

0 commit comments

Comments
 (0)