Skip to content

Commit 1bb5415

Browse files
phoflluckyvs1
authored andcommitted
BUG: Fixed regression in rolling.skew and rolling.kurt modifying object (pandas-dev#38909)
1 parent f0f7fe9 commit 1bb5415

File tree

3 files changed

+22
-18
lines changed

3 files changed

+22
-18
lines changed

doc/source/whatsnew/v1.2.1.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Fixed regressions
3737
- Fixed regression in :meth:`.GroupBy.sem` where the presence of non-numeric columns would cause an error instead of being dropped (:issue:`38774`)
3838
- Fixed regression in :func:`read_excel` with non-rawbyte file handles (:issue:`38788`)
3939
- Bug in :meth:`read_csv` with ``float_precision="high"`` caused segfault or wrong parsing of long exponent strings. This resulted in a regression in some cases as the default for ``float_precision`` was changed in pandas 1.2.0 (:issue:`38753`)
40-
-
40+
- Fixed regression in :meth:`Rolling.skew` and :meth:`Rolling.kurt` modifying the object inplace (:issue:`38908`)
4141

4242
.. ---------------------------------------------------------------------------
4343

pandas/_libs/window/aggregations.pyx

+14-12
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ def roll_skew(ndarray[float64_t] values, ndarray[int64_t] start,
495495
float64_t x = 0, xx = 0, xxx = 0
496496
int64_t nobs = 0, i, j, N = len(values), nobs_mean = 0
497497
int64_t s, e
498-
ndarray[float64_t] output, mean_array
498+
ndarray[float64_t] output, mean_array, values_copy
499499
bint is_monotonic_increasing_bounds
500500

501501
minp = max(minp, 3)
@@ -504,10 +504,11 @@ def roll_skew(ndarray[float64_t] values, ndarray[int64_t] start,
504504
)
505505
output = np.empty(N, dtype=float)
506506
min_val = np.nanmin(values)
507+
values_copy = np.copy(values)
507508

508509
with nogil:
509510
for i in range(0, N):
510-
val = values[i]
511+
val = values_copy[i]
511512
if notnan(val):
512513
nobs_mean += 1
513514
sum_val += val
@@ -516,7 +517,7 @@ def roll_skew(ndarray[float64_t] values, ndarray[int64_t] start,
516517
if min_val - mean_val > -1e5:
517518
mean_val = round(mean_val)
518519
for i in range(0, N):
519-
values[i] = values[i] - mean_val
520+
values_copy[i] = values_copy[i] - mean_val
520521

521522
for i in range(0, N):
522523

@@ -528,7 +529,7 @@ def roll_skew(ndarray[float64_t] values, ndarray[int64_t] start,
528529
if i == 0 or not is_monotonic_increasing_bounds:
529530

530531
for j in range(s, e):
531-
val = values[j]
532+
val = values_copy[j]
532533
add_skew(val, &nobs, &x, &xx, &xxx, &compensation_x_add,
533534
&compensation_xx_add, &compensation_xxx_add)
534535

@@ -538,13 +539,13 @@ def roll_skew(ndarray[float64_t] values, ndarray[int64_t] start,
538539
# and removed
539540
# calculate deletes
540541
for j in range(start[i - 1], s):
541-
val = values[j]
542+
val = values_copy[j]
542543
remove_skew(val, &nobs, &x, &xx, &xxx, &compensation_x_remove,
543544
&compensation_xx_remove, &compensation_xxx_remove)
544545

545546
# calculate adds
546547
for j in range(end[i - 1], e):
547-
val = values[j]
548+
val = values_copy[j]
548549
add_skew(val, &nobs, &x, &xx, &xxx, &compensation_x_add,
549550
&compensation_xx_add, &compensation_xxx_add)
550551

@@ -675,19 +676,20 @@ def roll_kurt(ndarray[float64_t] values, ndarray[int64_t] start,
675676
float64_t compensation_x_remove = 0, compensation_x_add = 0
676677
float64_t x = 0, xx = 0, xxx = 0, xxxx = 0
677678
int64_t nobs = 0, i, j, s, e, N = len(values), nobs_mean = 0
678-
ndarray[float64_t] output
679+
ndarray[float64_t] output, values_copy
679680
bint is_monotonic_increasing_bounds
680681

681682
minp = max(minp, 4)
682683
is_monotonic_increasing_bounds = is_monotonic_increasing_start_end_bounds(
683684
start, end
684685
)
685686
output = np.empty(N, dtype=float)
687+
values_copy = np.copy(values)
686688
min_val = np.nanmin(values)
687689

688690
with nogil:
689691
for i in range(0, N):
690-
val = values[i]
692+
val = values_copy[i]
691693
if notnan(val):
692694
nobs_mean += 1
693695
sum_val += val
@@ -696,7 +698,7 @@ def roll_kurt(ndarray[float64_t] values, ndarray[int64_t] start,
696698
if min_val - mean_val > -1e4:
697699
mean_val = round(mean_val)
698700
for i in range(0, N):
699-
values[i] = values[i] - mean_val
701+
values_copy[i] = values_copy[i] - mean_val
700702

701703
for i in range(0, N):
702704

@@ -708,7 +710,7 @@ def roll_kurt(ndarray[float64_t] values, ndarray[int64_t] start,
708710
if i == 0 or not is_monotonic_increasing_bounds:
709711

710712
for j in range(s, e):
711-
add_kurt(values[j], &nobs, &x, &xx, &xxx, &xxxx,
713+
add_kurt(values_copy[j], &nobs, &x, &xx, &xxx, &xxxx,
712714
&compensation_x_add, &compensation_xx_add,
713715
&compensation_xxx_add, &compensation_xxxx_add)
714716

@@ -718,13 +720,13 @@ def roll_kurt(ndarray[float64_t] values, ndarray[int64_t] start,
718720
# and removed
719721
# calculate deletes
720722
for j in range(start[i - 1], s):
721-
remove_kurt(values[j], &nobs, &x, &xx, &xxx, &xxxx,
723+
remove_kurt(values_copy[j], &nobs, &x, &xx, &xxx, &xxxx,
722724
&compensation_x_remove, &compensation_xx_remove,
723725
&compensation_xxx_remove, &compensation_xxxx_remove)
724726

725727
# calculate adds
726728
for j in range(end[i - 1], e):
727-
add_kurt(values[j], &nobs, &x, &xx, &xxx, &xxxx,
729+
add_kurt(values_copy[j], &nobs, &x, &xx, &xxx, &xxxx,
728730
&compensation_x_add, &compensation_xx_add,
729731
&compensation_xxx_add, &compensation_xxxx_add)
730732

pandas/tests/window/test_rolling.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -1102,11 +1102,13 @@ def test_groupby_rolling_nan_included():
11021102

11031103
@pytest.mark.parametrize("method", ["skew", "kurt"])
11041104
def test_rolling_skew_kurt_numerical_stability(method):
1105-
# GH: 6929
1106-
s = Series(np.random.rand(10))
1107-
expected = getattr(s.rolling(3), method)()
1108-
s = s + 50000
1109-
result = getattr(s.rolling(3), method)()
1105+
# GH#6929
1106+
ser = Series(np.random.rand(10))
1107+
ser_copy = ser.copy()
1108+
expected = getattr(ser.rolling(3), method)()
1109+
tm.assert_series_equal(ser, ser_copy)
1110+
ser = ser + 50000
1111+
result = getattr(ser.rolling(3), method)()
11101112
tm.assert_series_equal(result, expected)
11111113

11121114

0 commit comments

Comments
 (0)