@@ -810,6 +810,7 @@ def group_quantile(ndarray[float64_t, ndim=2] out,
810
810
ndarray[numeric , ndim = 1 ] values,
811
811
ndarray[intp_t] labels ,
812
812
ndarray[uint8_t] mask ,
813
+ const intp_t[:] sort_indexer ,
813
814
const float64_t[:] qs ,
814
815
str interpolation ) -> None:
815
816
"""
@@ -823,6 +824,8 @@ def group_quantile(ndarray[float64_t, ndim=2] out,
823
824
Array containing the values to apply the function against.
824
825
labels : ndarray[np.intp]
825
826
Array containing the unique group labels.
827
+ sort_indexer : ndarray[np.intp]
828
+ Indices describing sort order by values and labels.
826
829
qs : ndarray[float64_t]
827
830
The quantile values to search for.
828
831
interpolation : {'linear', 'lower', 'highest', 'nearest', 'midpoint'}
@@ -836,9 +839,9 @@ def group_quantile(ndarray[float64_t, ndim=2] out,
836
839
Py_ssize_t i , N = len (labels), ngroups , grp_sz , non_na_sz , k , nqs
837
840
Py_ssize_t grp_start = 0 , idx = 0
838
841
intp_t lab
839
- uint8_t interp
842
+ InterpolationEnumType interp
840
843
float64_t q_val , q_idx , frac , val , next_val
841
- ndarray[ int64_t] counts , non_na_counts , sort_arr
844
+ int64_t[::1 ] counts , non_na_counts
842
845
843
846
assert values.shape[0] == N
844
847
@@ -873,16 +876,6 @@ def group_quantile(ndarray[float64_t, ndim=2] out,
873
876
if not mask[i]:
874
877
non_na_counts[lab] += 1
875
878
876
- # Get an index of values sorted by labels and then values
877
- if labels.any():
878
- # Put '-1' (NaN) labels as the last group so it does not interfere
879
- # with the calculations.
880
- labels_for_lexsort = np.where(labels == - 1 , labels.max() + 1 , labels)
881
- else :
882
- labels_for_lexsort = labels
883
- order = (values, labels_for_lexsort)
884
- sort_arr = np.lexsort(order).astype(np.int64, copy = False )
885
-
886
879
with nogil:
887
880
for i in range (ngroups):
888
881
# Figure out how many group elements there are
@@ -900,7 +893,7 @@ def group_quantile(ndarray[float64_t, ndim=2] out,
900
893
# Casting to int will intentionally truncate result
901
894
idx = grp_start + < int64_t> (q_val * < float64_t> (non_na_sz - 1 ))
902
895
903
- val = values[sort_arr [idx]]
896
+ val = values[sort_indexer [idx]]
904
897
# If requested quantile falls evenly on a particular index
905
898
# then write that index's value out. Otherwise interpolate
906
899
q_idx = q_val * (non_na_sz - 1 )
@@ -909,7 +902,7 @@ def group_quantile(ndarray[float64_t, ndim=2] out,
909
902
if frac == 0.0 or interp == INTERPOLATION_LOWER:
910
903
out[i, k] = val
911
904
else :
912
- next_val = values[sort_arr [idx + 1 ]]
905
+ next_val = values[sort_indexer [idx + 1 ]]
913
906
if interp == INTERPOLATION_LINEAR:
914
907
out[i, k] = val + (next_val - val) * frac
915
908
elif interp == INTERPOLATION_HIGHER:
0 commit comments