@@ -18,7 +18,8 @@ cdef extern from "src/headers/cmath" namespace "std":
18
18
int signbit(float64_t) nogil
19
19
float64_t sqrt(float64_t x) nogil
20
20
21
- cimport pandas._libs.util as util
21
+ from pandas._libs.algos import is_monotonic
22
+
22
23
from pandas._libs.util cimport numeric
23
24
24
25
from pandas._libs.skiplist cimport (
37
38
cdef inline int int_max(int a, int b): return a if a >= b else b
38
39
cdef inline int int_min(int a, int b): return a if a <= b else b
39
40
41
+ cdef inline bint is_monotonic_start_end_bounds(ndarray[int64_t, ndim= 1 ] start,
42
+ ndarray[int64_t, ndim= 1 ] end):
43
+ return is_monotonic(start, False )[0 ] and is_monotonic(end, False )[0 ]
40
44
41
45
# Cython implementations of rolling sum, mean, variance, skewness,
42
46
# other statistical moment functions
@@ -48,39 +52,6 @@ cdef inline int int_min(int a, int b): return a if a <= b else b
48
52
# periodically revisited to see if it's still true.
49
53
#
50
54
51
-
52
- def _check_minp (win , minp , N , floor = None ) -> int:
53
- """
54
- Parameters
55
- ----------
56
- win: int
57
- minp: int or None
58
- N: len of window
59
- floor: int , optional
60
- default 1
61
-
62
- Returns
63
- -------
64
- minimum period
65
- """
66
-
67
- if minp is None:
68
- minp = 1
69
- if not util.is_integer_object(minp ):
70
- raise ValueError (" min_periods must be an integer" )
71
- if minp > win:
72
- raise ValueError (f" min_periods (minp) must be <= "
73
- f" window (win)" )
74
- elif minp > N:
75
- minp = N + 1
76
- elif minp < 0 :
77
- raise ValueError (' min_periods must be >= 0' )
78
- if floor is None :
79
- floor = 1
80
-
81
- return max (minp, floor)
82
-
83
-
84
55
# original C implementation by N. Devillard.
85
56
# This code in public domain.
86
57
# Function : kth_smallest()
@@ -96,7 +67,6 @@ def _check_minp(win, minp, N, floor=None) -> int:
96
67
# Physical description: 366 p.
97
68
# Series: Prentice-Hall Series in Automatic Computation
98
69
99
-
100
70
# ----------------------------------------------------------------------
101
71
# Rolling count
102
72
# this is only an impl for index not None, IOW, freq aware
@@ -183,14 +153,15 @@ cdef inline void remove_sum(float64_t val, int64_t *nobs, float64_t *sum_x) nogi
183
153
184
154
185
155
def roll_sum_variable (ndarray[float64_t] values , ndarray[int64_t] start ,
186
- ndarray[int64_t] end , int64_t minp ,
187
- bint is_monotonic_bounds = True ):
156
+ ndarray[int64_t] end , int64_t minp ):
188
157
cdef:
189
158
float64_t sum_x = 0
190
159
int64_t s, e
191
160
int64_t nobs = 0 , i, j, N = len (values)
192
161
ndarray[float64_t] output
162
+ bint is_monotonic_bounds
193
163
164
+ is_monotonic_bounds = is_monotonic_start_end_bounds(start, end)
194
165
output = np.empty(N, dtype = float )
195
166
196
167
with nogil:
@@ -331,14 +302,15 @@ def roll_mean_fixed(ndarray[float64_t] values, ndarray[int64_t] start,
331
302
332
303
333
304
def roll_mean_variable (ndarray[float64_t] values , ndarray[int64_t] start ,
334
- ndarray[int64_t] end , int64_t minp ,
335
- bint is_monotonic_bounds = True ):
305
+ ndarray[int64_t] end , int64_t minp ):
336
306
cdef:
337
307
float64_t val, sum_x = 0
338
308
int64_t s, e
339
309
Py_ssize_t nobs = 0 , i, j, neg_ct = 0 , N = len (values)
340
310
ndarray[float64_t] output
311
+ bint is_monotonic_bounds
341
312
313
+ is_monotonic_bounds = is_monotonic_start_end_bounds(start, end)
342
314
output = np.empty(N, dtype = float )
343
315
344
316
with nogil:
@@ -493,8 +465,7 @@ def roll_var_fixed(ndarray[float64_t] values, ndarray[int64_t] start,
493
465
494
466
495
467
def roll_var_variable (ndarray[float64_t] values , ndarray[int64_t] start ,
496
- ndarray[int64_t] end , int64_t minp , int ddof = 1 ,
497
- bint is_monotonic_bounds = True ):
468
+ ndarray[int64_t] end , int64_t minp , int ddof = 1 ):
498
469
"""
499
470
Numerically stable implementation using Welford's method.
500
471
"""
@@ -504,7 +475,9 @@ def roll_var_variable(ndarray[float64_t] values, ndarray[int64_t] start,
504
475
int64_t s, e
505
476
Py_ssize_t i, j, N = len (values)
506
477
ndarray[float64_t] output
478
+ bint is_monotonic_bounds
507
479
480
+ is_monotonic_bounds = is_monotonic_start_end_bounds(start, end)
508
481
output = np.empty(N, dtype = float )
509
482
510
483
with nogil:
@@ -641,15 +614,16 @@ def roll_skew_fixed(ndarray[float64_t] values, ndarray[int64_t] start,
641
614
642
615
643
616
def roll_skew_variable (ndarray[float64_t] values , ndarray[int64_t] start ,
644
- ndarray[int64_t] end , int64_t minp ,
645
- bint is_monotonic_bounds = True ):
617
+ ndarray[int64_t] end , int64_t minp ):
646
618
cdef:
647
619
float64_t val, prev
648
620
float64_t x = 0 , xx = 0 , xxx = 0
649
621
int64_t nobs = 0 , i, j, N = len (values)
650
622
int64_t s, e
651
623
ndarray[float64_t] output
624
+ bint is_monotonic_bounds
652
625
626
+ is_monotonic_bounds = is_monotonic_start_end_bounds(start, end)
653
627
output = np.empty(N, dtype = float )
654
628
655
629
with nogil:
@@ -794,14 +768,15 @@ def roll_kurt_fixed(ndarray[float64_t] values, ndarray[int64_t] start,
794
768
795
769
796
770
def roll_kurt_variable (ndarray[float64_t] values , ndarray[int64_t] start ,
797
- ndarray[int64_t] end , int64_t minp ,
798
- bint is_monotonic_bounds = True ):
771
+ ndarray[int64_t] end , int64_t minp ):
799
772
cdef:
800
773
float64_t val, prev
801
774
float64_t x = 0 , xx = 0 , xxx = 0 , xxxx = 0
802
775
int64_t nobs = 0 , i, j, s, e, N = len (values)
803
776
ndarray[float64_t] output
777
+ bint is_monotonic_bounds
804
778
779
+ is_monotonic_bounds = is_monotonic_start_end_bounds(start, end)
805
780
output = np.empty(N, dtype = float )
806
781
807
782
with nogil:
@@ -1030,8 +1005,7 @@ def roll_min_fixed(ndarray[float64_t] values, ndarray[int64_t] start,
1030
1005
1031
1006
1032
1007
def roll_min_variable (ndarray[float64_t] values , ndarray[int64_t] start ,
1033
- ndarray[int64_t] end , int64_t minp ,
1034
- bint is_monotonic_bounds = True ):
1008
+ ndarray[int64_t] end , int64_t minp ):
1035
1009
"""
1036
1010
Moving max of 1d array of any numeric type along axis=0 ignoring NaNs.
1037
1011
@@ -1424,10 +1398,7 @@ def roll_generic_variable(object obj,
1424
1398
ndarray[int64_t] start , ndarray[int64_t] end ,
1425
1399
int64_t minp ,
1426
1400
int offset , object func , bint raw ,
1427
- object args , object kwargs ,
1428
- bint is_monotonic_bounds = True ):
1429
- # is_monotonic_bounds unused since variable algorithm doesn't calculate
1430
- # adds/subtracts across windows, but matches other *_variable functions
1401
+ object args , object kwargs ):
1431
1402
cdef:
1432
1403
ndarray[float64_t] output, counts, bufarr
1433
1404
ndarray[float64_t, cast= True ] arr
@@ -1501,7 +1472,15 @@ cdef ndarray[float64_t] _roll_weighted_sum_mean(float64_t[:] values,
1501
1472
if avg:
1502
1473
tot_wgt = np.zeros(in_n, dtype = np.float64)
1503
1474
1504
- minp = _check_minp(len (weights), minp, in_n)
1475
+ if minp > win_n:
1476
+ raise ValueError (f" min_periods (minp) must be <= "
1477
+ f" window (win)" )
1478
+ elif minp > in_n:
1479
+ minp = in_n + 1
1480
+ elif minp < 0 :
1481
+ raise ValueError (' min_periods must be >= 0' )
1482
+
1483
+ minp = max (minp, 1 )
1505
1484
1506
1485
with nogil:
1507
1486
if avg:
0 commit comments