From 813d76e10d35db2c4916d2db59d688613a8f62e1 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Bethi Date: Wed, 15 Oct 2025 08:58:17 -0400 Subject: [PATCH 1/5] added condition to avoid max recursion depth --- pandas/core/arrays/sparse/array.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index e6ff67af78700..004e76ff82da6 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -1571,6 +1571,9 @@ def cumsum(self, axis: AxisInt = 0, *args, **kwargs) -> SparseArray: raise ValueError(f"axis(={axis}) out of bounds") if not self._null_fill_value: + if isinstance(self, SparseArray) and self.fill_value == 0: + # special case where we can avoid densifying + return SparseArray(self.to_dense().cumsum()) return SparseArray(self.to_dense()).cumsum() return SparseArray( From a3ff4818cb2bc1b4324e3fddfbb26c86dea6837f Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Bethi Date: Wed, 15 Oct 2025 08:58:52 -0400 Subject: [PATCH 2/5] added condition to avoid max recursion depth --- pandas/core/arrays/sparse/array.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index 004e76ff82da6..0602cea57ba90 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -1572,7 +1572,7 @@ def cumsum(self, axis: AxisInt = 0, *args, **kwargs) -> SparseArray: if not self._null_fill_value: if isinstance(self, SparseArray) and self.fill_value == 0: - # special case where we can avoid densifying + # special case where we can avoid max recursion depth return SparseArray(self.to_dense().cumsum()) return SparseArray(self.to_dense()).cumsum() From c550eacf810be7a12da8683fcfe92bf598934903 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Bethi Date: Wed, 15 Oct 2025 08:59:10 -0400 Subject: [PATCH 3/5] added entry in rst file --- doc/source/whatsnew/v3.0.0.rst | 1 + 1 file changed, 1 insertion(+) 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 ^^^^^^^^^^^^^^ From bc75673a9c9eaefe9adab7bc1e673364fb7bddae Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Bethi Date: Wed, 15 Oct 2025 08:59:28 -0400 Subject: [PATCH 4/5] added test cases --- pandas/tests/arrays/sparse/test_array.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) 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 From bfeb945859f2efc1874bd894b622d839158374e7 Mon Sep 17 00:00:00 2001 From: santhoshbethi <45058712+santhoshbethi@users.noreply.github.com> Date: Sun, 26 Oct 2025 16:13:38 -0400 Subject: [PATCH 5/5] Update pandas/core/arrays/sparse/array.py Co-authored-by: Richard Shadrach <45562402+rhshadrach@users.noreply.github.com> --- pandas/core/arrays/sparse/array.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index 0602cea57ba90..ca0e0f015b77f 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -1570,10 +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 isinstance(self, SparseArray) and self.fill_value == 0: - # special case where we can avoid max recursion depth - return SparseArray(self.to_dense().cumsum()) + if not self._null_fill_value and self.fill_value != 0: return SparseArray(self.to_dense()).cumsum() return SparseArray(