diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 0b7135b2d109d..53b84262a9208 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -1169,6 +1169,7 @@ Sparse - Bug in :class:`SparseDtype` for equal comparison with na fill value. (:issue:`54770`) - Bug in :meth:`DataFrame.sparse.from_spmatrix` which hard coded an invalid ``fill_value`` for certain subtypes. (:issue:`59063`) - Bug in :meth:`DataFrame.sparse.to_dense` which ignored subclassing and always returned an instance of :class:`DataFrame` (:issue:`59913`) +- Bug in :meth:`cumsum` for integer arrays Calling SparseArray.cumsum caused max recursion depth error. (:issue:`62669`) ExtensionArray ^^^^^^^^^^^^^^ diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index e6ff67af78700..ca0e0f015b77f 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -1570,7 +1570,7 @@ def cumsum(self, axis: AxisInt = 0, *args, **kwargs) -> SparseArray: if axis is not None and axis >= self.ndim: # Mimic ndarray behaviour. raise ValueError(f"axis(={axis}) out of bounds") - if not self._null_fill_value: + if not self._null_fill_value and self.fill_value != 0: return SparseArray(self.to_dense()).cumsum() return SparseArray( diff --git a/pandas/tests/arrays/sparse/test_array.py b/pandas/tests/arrays/sparse/test_array.py index 1b685100e4931..f382dc80aa216 100644 --- a/pandas/tests/arrays/sparse/test_array.py +++ b/pandas/tests/arrays/sparse/test_array.py @@ -363,6 +363,20 @@ def test_setting_fill_value_fillna_still_works(): tm.assert_numpy_array_equal(result, expected) +def test_cumsum_integer_no_recursion(): + # GH 62669: RecursionError in integer SparseArray.cumsum + arr = SparseArray([1, 2, 3]) + result = arr.cumsum() + expected = SparseArray([1, 3, 6]) + tm.assert_sp_array_equal(result, expected) + + # Also test with some zeros interleaved + arr2 = SparseArray([0, 1, 0, 2]) + result2 = arr2.cumsum() + expected2 = SparseArray([0, 1, 1, 3]) + tm.assert_sp_array_equal(result2, expected2) + + def test_setting_fill_value_updates(): arr = SparseArray([0.0, np.nan], fill_value=0) arr.fill_value = np.nan