@@ -30,8 +30,8 @@ from numpy.math cimport NAN
30
30
31
31
cnp.import_array()
32
32
33
+ from pandas._libs cimport util
33
34
from pandas._libs.algos cimport kth_smallest_c
34
- from pandas._libs.util cimport get_nat
35
35
36
36
from pandas._libs.algos import (
37
37
ensure_platform_int,
@@ -49,7 +49,7 @@ from pandas._libs.dtypes cimport (
49
49
from pandas._libs.missing cimport checknull
50
50
51
51
52
- cdef int64_t NPY_NAT = get_nat()
52
+ cdef int64_t NPY_NAT = util. get_nat()
53
53
_int64_max = np.iinfo(np.int64).max
54
54
55
55
cdef float64_t NaN = < float64_t> np.NaN
@@ -248,13 +248,7 @@ def group_cumsum(
248
248
accum = np.zeros((ngroups, K), dtype = np.asarray(values).dtype)
249
249
compensation = np.zeros((ngroups, K), dtype = np.asarray(values).dtype)
250
250
251
- if numeric_t == float32_t or numeric_t == float64_t:
252
- na_val = NaN
253
- elif numeric_t is int64_t and is_datetimelike:
254
- na_val = NPY_NAT
255
- else:
256
- # Will not be used , but define to avoid unitialized warning.
257
- na_val = 0
251
+ na_val = _get_na_val(< numeric_t> 0 , is_datetimelike)
258
252
259
253
with nogil:
260
254
for i in range(N ):
@@ -995,6 +989,47 @@ cdef inline bint _treat_as_na(numeric_object_t val, bint is_datetimelike) nogil:
995
989
return False
996
990
997
991
992
+ cdef numeric_t _get_min_or_max(numeric_t val, bint compute_max):
993
+ """
994
+ Find either the min or the max supported by numeric_t; 'val' is a placeholder
995
+ to effectively make numeric_t an argument.
996
+ """
997
+ if numeric_t is int64_t:
998
+ return - _int64_max if compute_max else util.INT64_MAX
999
+ elif numeric_t is int32_t:
1000
+ return util.INT32_MIN if compute_max else util.INT32_MAX
1001
+ elif numeric_t is int16_t:
1002
+ return util.INT16_MIN if compute_max else util.INT16_MAX
1003
+ elif numeric_t is int8_t:
1004
+ return util.INT8_MIN if compute_max else util.INT8_MAX
1005
+
1006
+ elif numeric_t is uint64_t:
1007
+ return 0 if compute_max else util.UINT64_MAX
1008
+ elif numeric_t is uint32_t:
1009
+ return 0 if compute_max else util.UINT32_MAX
1010
+ elif numeric_t is uint16_t:
1011
+ return 0 if compute_max else util.UINT16_MAX
1012
+ elif numeric_t is uint8_t:
1013
+ return 0 if compute_max else util.UINT8_MAX
1014
+
1015
+ else :
1016
+ return - np.inf if compute_max else np.inf
1017
+
1018
+
1019
+ cdef numeric_t _get_na_val(numeric_t val, bint is_datetimelike):
1020
+ cdef:
1021
+ numeric_t na_val
1022
+
1023
+ if numeric_t == float32_t or numeric_t == float64_t:
1024
+ na_val = NaN
1025
+ elif numeric_t is int64_t and is_datetimelike:
1026
+ na_val = NPY_NAT
1027
+ else :
1028
+ # Will not be used, but define to avoid unitialized warning.
1029
+ na_val = 0
1030
+ return na_val
1031
+
1032
+
998
1033
# TODO(cython3): GH#31710 use memorviews once cython 0.30 is released so we can
999
1034
# use `const iu_64_floating_obj_t[:, :] values`
1000
1035
@ cython.wraparound (False )
@@ -1359,16 +1394,17 @@ cdef group_min_max(
1359
1394
nobs = np.zeros((< object > out).shape, dtype = np.int64)
1360
1395
1361
1396
group_min_or_max = np.empty_like(out)
1397
+ group_min_or_max[:] = _get_min_or_max(< iu_64_floating_t> 0 , compute_max)
1398
+
1362
1399
if iu_64_floating_t is int64_t:
1363
- group_min_or_max[:] = - _int64_max if compute_max else _int64_max
1400
+ # TODO: only if is_datetimelike?
1364
1401
nan_val = NPY_NAT
1365
1402
elif iu_64_floating_t is uint64_t:
1366
1403
# NB: We do not define nan_val because there is no such thing
1367
1404
# for uint64_t. We carefully avoid having to reference it in this
1368
1405
# case.
1369
- group_min_or_max[:] = 0 if compute_max else np.iinfo(np.uint64).max
1406
+ pass
1370
1407
else :
1371
- group_min_or_max[:] = - np.inf if compute_max else np.inf
1372
1408
nan_val = NAN
1373
1409
1374
1410
N, K = (< object > values).shape
@@ -1527,26 +1563,20 @@ cdef group_cummin_max(
1527
1563
bint isna_entry
1528
1564
1529
1565
accum = np.empty((ngroups, (< object > values).shape[1 ]), dtype = values.dtype)
1530
- if iu_64_floating_t is int64_t:
1531
- accum[:] = - _int64_max if compute_max else _int64_max
1532
- elif iu_64_floating_t is uint64_t:
1533
- accum[:] = 0 if compute_max else np.iinfo(np.uint64).max
1534
- else :
1535
- accum[:] = - np.inf if compute_max else np.inf
1566
+ accum[:] = _get_min_or_max(< iu_64_floating_t> 0 , compute_max)
1567
+
1568
+ na_val = _get_na_val(< iu_64_floating_t> 0 , is_datetimelike)
1536
1569
1537
1570
if uses_mask:
1538
1571
na_possible = True
1539
1572
# Will never be used, just to avoid uninitialized warning
1540
1573
na_val = 0
1541
1574
elif iu_64_floating_t is float64_t or iu_64_floating_t is float32_t:
1542
- na_val = NaN
1543
1575
na_possible = True
1544
1576
elif is_datetimelike:
1545
- na_val = NPY_NAT
1546
1577
na_possible = True
1547
1578
else :
1548
1579
# Will never be used, just to avoid uninitialized warning
1549
- na_val = 0
1550
1580
na_possible = False
1551
1581
1552
1582
if na_possible:
0 commit comments