@@ -1382,14 +1382,15 @@ def roll_quantile(ndarray[float64_t, cast=True] input, int64_t win,
1382
1382
"""
1383
1383
cdef:
1384
1384
double val, prev, midpoint, idx_with_fraction
1385
- IndexableSkiplist skiplist
1385
+ skiplist_t * skiplist
1386
1386
int64_t nobs = 0 , i, j, s, e, N
1387
1387
Py_ssize_t idx
1388
1388
bint is_variable
1389
1389
ndarray[int64_t] start, end
1390
1390
ndarray[double_t] output
1391
1391
double vlow, vhigh
1392
1392
InterpolationType interpolation_type
1393
+ int ret = 0
1393
1394
1394
1395
if quantile <= 0.0 or quantile >= 1.0 :
1395
1396
raise ValueError (" quantile value {0} not in [0, 1]" .format(quantile))
@@ -1407,75 +1408,78 @@ def roll_quantile(ndarray[float64_t, cast=True] input, int64_t win,
1407
1408
minp, index, closed,
1408
1409
use_mock = False )
1409
1410
output = np.empty(N, dtype = float )
1410
- skiplist = IndexableSkiplist(win)
1411
-
1412
- for i in range (0 , N):
1413
- s = start[i]
1414
- e = end[i]
1415
-
1416
- if i == 0 :
1417
-
1418
- # setup
1419
- val = input [i]
1420
- if val == val:
1421
- nobs += 1
1422
- skiplist.insert(val)
1411
+ skiplist = skiplist_init(< int > win)
1412
+ if skiplist == NULL :
1413
+ raise MemoryError (" skiplist_init failed" )
1423
1414
1424
- else :
1415
+ with nogil:
1416
+ for i in range (0 , N):
1417
+ s = start[i]
1418
+ e = end[i]
1425
1419
1426
- # calculate deletes
1427
- for j in range (start[i - 1 ], s):
1428
- val = input [j]
1429
- if val == val:
1430
- skiplist.remove(val)
1431
- nobs -= 1
1420
+ if i == 0 :
1432
1421
1433
- # calculate adds
1434
- for j in range (end[i - 1 ], e):
1435
- val = input [j]
1422
+ # setup
1423
+ val = input [i]
1436
1424
if val == val:
1437
1425
nobs += 1
1438
- skiplist.insert( val)
1426
+ skiplist_insert(skiplist, val)
1439
1427
1440
- if nobs >= minp:
1441
- if nobs == 1 :
1442
- # Single value in skip list
1443
- output[i] = skiplist.get(0 )
1444
1428
else :
1445
- idx_with_fraction = quantile * (nobs - 1 )
1446
- idx = < int > idx_with_fraction
1447
-
1448
- if idx_with_fraction == idx:
1449
- # no need to interpolate
1450
- output[i] = skiplist.get(idx)
1451
- continue
1452
-
1453
- if interpolation_type == LINEAR:
1454
- vlow = skiplist.get(idx)
1455
- vhigh = skiplist.get(idx + 1 )
1456
- output[i] = ((vlow + (vhigh - vlow) *
1457
- (idx_with_fraction - idx)))
1458
- elif interpolation_type == LOWER:
1459
- output[i] = skiplist.get(idx)
1460
- elif interpolation_type == HIGHER:
1461
- output[i] = skiplist.get(idx + 1 )
1462
- elif interpolation_type == NEAREST:
1463
- # the same behaviour as round()
1464
- if idx_with_fraction - idx == 0.5 :
1465
- if idx % 2 == 0 :
1466
- output[i] = skiplist.get(idx)
1429
+
1430
+ # calculate deletes
1431
+ for j in range (start[i - 1 ], s):
1432
+ val = input [j]
1433
+ if val == val:
1434
+ skiplist_remove(skiplist, val)
1435
+ nobs -= 1
1436
+
1437
+ # calculate adds
1438
+ for j in range (end[i - 1 ], e):
1439
+ val = input [j]
1440
+ if val == val:
1441
+ nobs += 1
1442
+ skiplist_insert(skiplist, val)
1443
+
1444
+ if nobs >= minp:
1445
+ if nobs == 1 :
1446
+ # Single value in skip list
1447
+ output[i] = skiplist_get(skiplist, 0 , & ret)
1448
+ else :
1449
+ idx_with_fraction = quantile * (nobs - 1 )
1450
+ idx = < int > idx_with_fraction
1451
+
1452
+ if idx_with_fraction == idx:
1453
+ # no need to interpolate
1454
+ output[i] = skiplist_get(skiplist, idx, & ret)
1455
+ continue
1456
+
1457
+ if interpolation_type == LINEAR:
1458
+ vlow = skiplist_get(skiplist, idx, & ret)
1459
+ vhigh = skiplist_get(skiplist, idx + 1 , & ret)
1460
+ output[i] = ((vlow + (vhigh - vlow) *
1461
+ (idx_with_fraction - idx)))
1462
+ elif interpolation_type == LOWER:
1463
+ output[i] = skiplist_get(skiplist, idx, & ret)
1464
+ elif interpolation_type == HIGHER:
1465
+ output[i] = skiplist_get(skiplist, idx + 1 , & ret)
1466
+ elif interpolation_type == NEAREST:
1467
+ # the same behaviour as round()
1468
+ if idx_with_fraction - idx == 0.5 :
1469
+ if idx % 2 == 0 :
1470
+ output[i] = skiplist_get(skiplist, idx, & ret)
1471
+ else :
1472
+ output[i] = skiplist_get(skiplist, idx + 1 , & ret)
1473
+ elif idx_with_fraction - idx < 0.5 :
1474
+ output[i] = skiplist_get(skiplist, idx, & ret)
1467
1475
else :
1468
- output[i] = skiplist.get(idx + 1 )
1469
- elif idx_with_fraction - idx < 0.5 :
1470
- output[i] = skiplist.get(idx)
1471
- else :
1472
- output[i] = skiplist.get(idx + 1 )
1473
- elif interpolation_type == MIDPOINT:
1474
- vlow = skiplist.get(idx)
1475
- vhigh = skiplist.get(idx + 1 )
1476
- output[i] = < double > (vlow + vhigh) / 2
1477
- else :
1478
- output[i] = NaN
1476
+ output[i] = skiplist_get(skiplist, idx + 1 , & ret)
1477
+ elif interpolation_type == MIDPOINT:
1478
+ vlow = skiplist_get(skiplist, idx, & ret)
1479
+ vhigh = skiplist_get(skiplist, idx + 1 , & ret)
1480
+ output[i] = < double > (vlow + vhigh) / 2
1481
+ else :
1482
+ output[i] = NaN
1479
1483
1480
1484
return output
1481
1485
0 commit comments