@@ -161,7 +161,8 @@ cdef class MockFixedWindowIndexer(WindowIndexer):
161
161
162
162
"""
163
163
def __init__ (self , ndarray input , int64_t win , int64_t minp ,
164
- object index = None , object floor = None , closed = ' right' ):
164
+ object index = None , object floor = None ,
165
+ bint l_closed = False , bint r_closed = True ):
165
166
166
167
assert index is None
167
168
self .is_variable = 0
@@ -194,7 +195,8 @@ cdef class FixedWindowIndexer(WindowIndexer):
194
195
195
196
"""
196
197
def __init__ (self , ndarray input , int64_t win , int64_t minp ,
197
- object index = None , object floor = None , closed = ' right' ):
198
+ object index = None , object floor = None ,
199
+ bint l_closed = False , bint r_closed = True ):
198
200
cdef ndarray start_s, start_e, end_s, end_e
199
201
200
202
assert index is None
@@ -232,7 +234,7 @@ cdef class VariableWindowIndexer(WindowIndexer):
232
234
233
235
"""
234
236
def __init__ (self , ndarray input , int64_t win , int64_t minp ,
235
- ndarray index , closed = ' right ' ):
237
+ ndarray index , bint l_closed = False , bint r_closed = True ):
236
238
237
239
self .is_variable = 1
238
240
self .N = len (index)
@@ -244,27 +246,14 @@ cdef class VariableWindowIndexer(WindowIndexer):
244
246
self .end = np.empty(self .N, dtype = ' int64' )
245
247
self .end.fill(- 1 )
246
248
247
- cdef:
248
- bint leftIsClosed = False
249
- bint rightIsClosed = False
250
-
251
- if closed not in [' right' , ' left' , ' both' , ' neither' ]:
252
- closed = ' right'
253
-
254
- if closed in [' right' , ' both' ]:
255
- rightIsClosed = True
256
-
257
- if closed in [' left' , ' both' ]:
258
- leftIsClosed = True
259
-
260
- self .build(index, win, leftIsClosed, rightIsClosed)
249
+ self .build(index, win, l_closed, r_closed)
261
250
262
251
# max window size
263
252
self .win = (self .end - self .start).max()
264
253
265
254
266
- def build (self , ndarray[int64_t] index , int64_t win , bint leftIsClosed ,
267
- bint rightIsClosed ):
255
+ def build (self , ndarray[int64_t] index , int64_t win , bint l_closed ,
256
+ bint r_closed ):
268
257
269
258
cdef:
270
259
ndarray[int64_t] start, end
@@ -276,10 +265,10 @@ cdef class VariableWindowIndexer(WindowIndexer):
276
265
N = self .N
277
266
278
267
start[0 ] = 0
279
- # if closed in ['right', 'both']:
280
- if rightIsClosed:
268
+
269
+ if r_closed: # right endpoint is closed
281
270
end[0 ] = 1
282
- else :
271
+ else : # right endpoint is open
283
272
end[0 ] = 0
284
273
285
274
with nogil:
@@ -290,8 +279,7 @@ cdef class VariableWindowIndexer(WindowIndexer):
290
279
end_bound = index[i]
291
280
start_bound = index[i] - win
292
281
293
- # if closed in ['left', 'both']:
294
- if leftIsClosed:
282
+ if l_closed: # left endpoint is closed
295
283
start_bound -= 1
296
284
297
285
# advance the start bound until we are
@@ -309,13 +297,13 @@ cdef class VariableWindowIndexer(WindowIndexer):
309
297
else :
310
298
end[i] = end[i - 1 ]
311
299
312
- # if closed in ['left', 'neither']:
313
- if not rightIsClosed :
300
+ # right endpoint is open
301
+ if not r_closed :
314
302
end[i] -= 1
315
303
316
304
317
- def get_window_indexer (input , win , minp , index , floor = None ,
318
- use_mock = True , closed = ' right ' ):
305
+ def get_window_indexer (input , win , minp , index , closed ,
306
+ floor = None , use_mock = True ):
319
307
"""
320
308
return the correct window indexer for the computation
321
309
@@ -341,12 +329,28 @@ def get_window_indexer(input, win, minp, index, floor=None,
341
329
342
330
"""
343
331
332
+ cdef:
333
+ bint l_closed = False
334
+ bint r_closed = False
335
+
336
+ if closed not in [' right' , ' left' , ' both' , ' neither' ]:
337
+ closed = ' right'
338
+
339
+ if closed in [' right' , ' both' ]:
340
+ r_closed = True
341
+
342
+ if closed in [' left' , ' both' ]:
343
+ l_closed = True
344
+
344
345
if index is not None :
345
- indexer = VariableWindowIndexer(input , win, minp, index, closed)
346
+ indexer = VariableWindowIndexer(input , win, minp, index, l_closed,
347
+ r_closed)
346
348
elif use_mock:
347
- indexer = MockFixedWindowIndexer(input , win, minp, index, floor, closed)
349
+ indexer = MockFixedWindowIndexer(input , win, minp, index, floor,
350
+ l_closed, r_closed)
348
351
else :
349
- indexer = FixedWindowIndexer(input , win, minp, index, floor, closed)
352
+ indexer = FixedWindowIndexer(input , win, minp, index, floor, l_closed,
353
+ r_closed)
350
354
return indexer.get_data()
351
355
352
356
# ----------------------------------------------------------------------
@@ -436,7 +440,7 @@ cdef inline void remove_sum(double val, int64_t *nobs, double *sum_x) nogil:
436
440
437
441
438
442
def roll_sum (ndarray[double_t] input , int64_t win , int64_t minp ,
439
- object index , closed = ' right ' ):
443
+ object index , str closed ):
440
444
cdef:
441
445
double val, prev_x, sum_x = 0
442
446
int64_t s, e
@@ -552,7 +556,7 @@ cdef inline void remove_mean(double val, Py_ssize_t *nobs, double *sum_x,
552
556
553
557
554
558
def roll_mean (ndarray[double_t] input , int64_t win , int64_t minp ,
555
- object index , closed = ' right ' ):
559
+ object index , str closed ):
556
560
cdef:
557
561
double val, prev_x, result, sum_x = 0
558
562
int64_t s, e
@@ -677,7 +681,7 @@ cdef inline void remove_var(double val, double *nobs, double *mean_x,
677
681
678
682
679
683
def roll_var (ndarray[double_t] input , int64_t win , int64_t minp ,
680
- object index , closed = ' right ' , int ddof = 1 ):
684
+ object index , str closed , int ddof = 1 ):
681
685
"""
682
686
Numerically stable implementation using Welford's method.
683
687
"""
@@ -820,7 +824,7 @@ cdef inline void remove_skew(double val, int64_t *nobs, double *x, double *xx,
820
824
821
825
822
826
def roll_skew (ndarray[double_t] input , int64_t win , int64_t minp ,
823
- object index , closed = ' right ' ):
827
+ object index , str closed ):
824
828
cdef:
825
829
double val, prev
826
830
double x = 0 , xx = 0 , xxx = 0
@@ -948,7 +952,7 @@ cdef inline void remove_kurt(double val, int64_t *nobs, double *x, double *xx,
948
952
949
953
950
954
def roll_kurt (ndarray[double_t] input , int64_t win , int64_t minp ,
951
- object index , closed = ' right ' ):
955
+ object index , str closed ):
952
956
cdef:
953
957
double val, prev
954
958
double x = 0 , xx = 0 , xxx = 0 , xxxx = 0
@@ -1018,7 +1022,7 @@ def roll_kurt(ndarray[double_t] input, int64_t win, int64_t minp,
1018
1022
1019
1023
1020
1024
def roll_median_c (ndarray[float64_t] input , int64_t win , int64_t minp ,
1021
- object index , closed = ' right ' ):
1025
+ object index , str closed ):
1022
1026
cdef:
1023
1027
double val, res, prev
1024
1028
bint err= 0 , is_variable
@@ -1034,8 +1038,8 @@ def roll_median_c(ndarray[float64_t] input, int64_t win, int64_t minp,
1034
1038
# actual skiplist ops outweigh any window computation costs
1035
1039
start, end, N, win, minp, is_variable = get_window_indexer(
1036
1040
input , win,
1037
- minp, index,
1038
- use_mock = False , closed = closed )
1041
+ minp, index, closed,
1042
+ use_mock = False )
1039
1043
output = np.empty(N, dtype = float )
1040
1044
1041
1045
sl = skiplist_init(< int > win)
@@ -1144,7 +1148,7 @@ cdef inline numeric calc_mm(int64_t minp, Py_ssize_t nobs,
1144
1148
1145
1149
1146
1150
def roll_max (ndarray[numeric] input , int64_t win , int64_t minp ,
1147
- object index , closed = ' right ' ):
1151
+ object index , str closed ):
1148
1152
"""
1149
1153
Moving max of 1d array of any numeric type along axis=0 ignoring NaNs.
1150
1154
@@ -1160,11 +1164,11 @@ def roll_max(ndarray[numeric] input, int64_t win, int64_t minp,
1160
1164
make the interval closed on the right, left,
1161
1165
both or neither endpoints
1162
1166
"""
1163
- return _roll_min_max(input , win, minp, index, is_max = 1 , closed = closed )
1167
+ return _roll_min_max(input , win, minp, index, closed = closed, is_max = 1 )
1164
1168
1165
1169
1166
1170
def roll_min (ndarray[numeric] input , int64_t win , int64_t minp ,
1167
- object index , closed = ' right ' ):
1171
+ object index , str closed ):
1168
1172
"""
1169
1173
Moving max of 1d array of any numeric type along axis=0 ignoring NaNs.
1170
1174
@@ -1181,7 +1185,7 @@ def roll_min(ndarray[numeric] input, int64_t win, int64_t minp,
1181
1185
1182
1186
1183
1187
cdef _roll_min_max(ndarray[numeric] input , int64_t win, int64_t minp,
1184
- object index, bint is_max, closed = ' right ' ):
1188
+ object index, str closed, bint is_max ):
1185
1189
"""
1186
1190
Moving min/max of 1d array of any numeric type along axis=0
1187
1191
ignoring NaNs.
@@ -1206,7 +1210,7 @@ cdef _roll_min_max(ndarray[numeric] input, int64_t win, int64_t minp,
1206
1210
1207
1211
starti, endi, N, win, minp, is_variable = get_window_indexer(
1208
1212
input , win,
1209
- minp, index, closed = closed )
1213
+ minp, index, closed)
1210
1214
1211
1215
output = np.empty(N, dtype = input .dtype)
1212
1216
@@ -1308,7 +1312,8 @@ cdef _roll_min_max(ndarray[numeric] input, int64_t win, int64_t minp,
1308
1312
1309
1313
1310
1314
def roll_quantile (ndarray[float64_t , cast = True ] input , int64_t win ,
1311
- int64_t minp , object index , double quantile , closed = ' right' ):
1315
+ int64_t minp , object index , str closed ,
1316
+ double quantile ):
1312
1317
"""
1313
1318
O(N log(window)) implementation using skip list
1314
1319
"""
@@ -1328,8 +1333,8 @@ def roll_quantile(ndarray[float64_t, cast=True] input, int64_t win,
1328
1333
# actual skiplist ops outweigh any window computation costs
1329
1334
start, end, N, win, minp, is_variable = get_window_indexer(
1330
1335
input , win,
1331
- minp, index,
1332
- use_mock = False , closed = closed )
1336
+ minp, index, closed,
1337
+ use_mock = False )
1333
1338
output = np.empty(N, dtype = float )
1334
1339
skiplist = IndexableSkiplist(win)
1335
1340
@@ -1371,9 +1376,9 @@ def roll_quantile(ndarray[float64_t, cast=True] input, int64_t win,
1371
1376
1372
1377
1373
1378
def roll_generic (ndarray[float64_t , cast = True ] input ,
1374
- int64_t win , int64_t minp , object index ,
1379
+ int64_t win , int64_t minp , object index , str closed ,
1375
1380
int offset , object func ,
1376
- object args , object kwargs , closed = ' right ' ):
1381
+ object args , object kwargs ):
1377
1382
cdef:
1378
1383
ndarray[double_t] output, counts, bufarr
1379
1384
float64_t * buf
@@ -1391,8 +1396,8 @@ def roll_generic(ndarray[float64_t, cast=True] input,
1391
1396
1392
1397
start, end, N, win, minp, is_variable = get_window_indexer(input , win,
1393
1398
minp, index,
1394
- floor = 0 ,
1395
- closed = closed )
1399
+ closed ,
1400
+ floor = 0 )
1396
1401
output = np.empty(N, dtype = float )
1397
1402
1398
1403
counts = roll_sum(np.concatenate([np.isfinite(input ).astype(float ),
0 commit comments