@@ -957,6 +957,8 @@ def group_last(iu_64_floating_obj_t[:, ::1] out,
957
957
int64_t[::1] counts ,
958
958
ndarray[iu_64_floating_obj_t , ndim = 2 ] values,
959
959
const intp_t[::1] labels ,
960
+ const uint8_t[:, :] mask ,
961
+ uint8_t[:, ::1] result_mask = None ,
960
962
Py_ssize_t min_count = - 1 ) -> None:
961
963
"""
962
964
Only aggregates on axis = 0
@@ -967,6 +969,8 @@ def group_last(iu_64_floating_obj_t[:, ::1] out,
967
969
ndarray[iu_64_floating_obj_t , ndim = 2 ] resx
968
970
ndarray[int64_t , ndim = 2 ] nobs
969
971
bint runtime_error = False
972
+ bint uses_mask = mask is not None
973
+ bint isna_entry
970
974
971
975
# TODO(cython3 ):
972
976
# Instead of `labels.shape[0]` use `len(labels)`
@@ -993,7 +997,12 @@ def group_last(iu_64_floating_obj_t[:, ::1] out,
993
997
for j in range (K):
994
998
val = values[i, j]
995
999
996
- if not checknull(val):
1000
+ if uses_mask:
1001
+ isna_entry = mask[i, j]
1002
+ else :
1003
+ isna_entry = checknull(val)
1004
+
1005
+ if not isna_entry:
997
1006
# NB: use _treat_as_na here once
998
1007
# conditional-nogil is available.
999
1008
nobs[lab, j] += 1
@@ -1016,15 +1025,23 @@ def group_last(iu_64_floating_obj_t[:, ::1] out,
1016
1025
for j in range (K):
1017
1026
val = values[i, j]
1018
1027
1019
- if not _treat_as_na(val, True ):
1028
+ if uses_mask:
1029
+ isna_entry = mask[i, j]
1030
+ else :
1031
+ isna_entry = _treat_as_na(val, True )
1020
1032
# TODO: Sure we always want is_datetimelike=True?
1033
+
1034
+ if not isna_entry:
1021
1035
nobs[lab, j] += 1
1022
1036
resx[lab, j] = val
1023
1037
1024
1038
for i in range (ncounts):
1025
1039
for j in range (K):
1026
1040
if nobs[i, j] < min_count:
1027
- if iu_64_floating_obj_t is int64_t:
1041
+ if uses_mask:
1042
+ result_mask[i, j] = True
1043
+ elif iu_64_floating_obj_t is int64_t:
1044
+ # TODO: only if datetimelike?
1028
1045
out[i, j] = NPY_NAT
1029
1046
elif iu_64_floating_obj_t is uint64_t:
1030
1047
runtime_error = True
0 commit comments