@@ -68,12 +68,14 @@ cdef:
6868 int TIEBREAK_MAX = 2
6969 int TIEBREAK_FIRST = 3
7070 int TIEBREAK_FIRST_DESCENDING = 4
71+ int TIEBREAK_DENSE = 5
7172
7273tiebreakers = {
7374 ' average' : TIEBREAK_AVERAGE,
7475 ' min' : TIEBREAK_MIN,
7576 ' max' : TIEBREAK_MAX,
76- ' first' : TIEBREAK_FIRST
77+ ' first' : TIEBREAK_FIRST,
78+ ' dense' : TIEBREAK_DENSE,
7779}
7880
7981
@@ -137,7 +139,7 @@ def rank_1d_float64(object in_arr, ties_method='average', ascending=True,
137139 """
138140
139141 cdef:
140- Py_ssize_t i, j, n, dups = 0
142+ Py_ssize_t i, j, n, dups = 0 , total_tie_count = 0
141143 ndarray[float64_t] sorted_data, ranks, values
142144 ndarray[int64_t] argsorted
143145 float64_t val, nan_value
@@ -200,6 +202,10 @@ def rank_1d_float64(object in_arr, ties_method='average', ascending=True,
200202 elif tiebreak == TIEBREAK_FIRST_DESCENDING:
201203 for j in range (i - dups + 1 , i + 1 ):
202204 ranks[argsorted[j]] = 2 * i - j - dups + 2
205+ elif tiebreak == TIEBREAK_DENSE:
206+ total_tie_count += 1
207+ for j in range (i - dups + 1 , i + 1 ):
208+ ranks[argsorted[j]] = total_tie_count
203209 sum_ranks = dups = 0
204210 if pct:
205211 return ranks / count
@@ -214,7 +220,7 @@ def rank_1d_int64(object in_arr, ties_method='average', ascending=True,
214220 """
215221
216222 cdef:
217- Py_ssize_t i, j, n, dups = 0
223+ Py_ssize_t i, j, n, dups = 0 , total_tie_count = 0
218224 ndarray[int64_t] sorted_data, values
219225 ndarray[float64_t] ranks
220226 ndarray[int64_t] argsorted
@@ -265,6 +271,10 @@ def rank_1d_int64(object in_arr, ties_method='average', ascending=True,
265271 elif tiebreak == TIEBREAK_FIRST_DESCENDING:
266272 for j in range (i - dups + 1 , i + 1 ):
267273 ranks[argsorted[j]] = 2 * i - j - dups + 2
274+ elif tiebreak == TIEBREAK_DENSE:
275+ total_tie_count += 1
276+ for j in range (i - dups + 1 , i + 1 ):
277+ ranks[argsorted[j]] = total_tie_count
268278 sum_ranks = dups = 0
269279 if pct:
270280 return ranks / count
@@ -279,7 +289,7 @@ def rank_2d_float64(object in_arr, axis=0, ties_method='average',
279289 """
280290
281291 cdef:
282- Py_ssize_t i, j, z, k, n, dups = 0
292+ Py_ssize_t i, j, z, k, n, dups = 0 , total_tie_count = 0
283293 ndarray[float64_t, ndim= 2 ] ranks, values
284294 ndarray[int64_t, ndim= 2 ] argsorted
285295 float64_t val, nan_value
@@ -324,6 +334,7 @@ def rank_2d_float64(object in_arr, axis=0, ties_method='average',
324334
325335 for i in range (n):
326336 dups = sum_ranks = 0
337+ total_tie_count = 0
327338 for j in range (k):
328339 sum_ranks += j + 1
329340 dups += 1
@@ -347,6 +358,10 @@ def rank_2d_float64(object in_arr, axis=0, ties_method='average',
347358 elif tiebreak == TIEBREAK_FIRST_DESCENDING:
348359 for z in range (j - dups + 1 , j + 1 ):
349360 ranks[i, argsorted[i, z]] = 2 * j - z - dups + 2
361+ elif tiebreak == TIEBREAK_DENSE:
362+ total_tie_count += 1
363+ for z in range (j - dups + 1 , j + 1 ):
364+ ranks[i, argsorted[i, z]] = total_tie_count
350365 sum_ranks = dups = 0
351366
352367 if axis == 0 :
@@ -362,7 +377,7 @@ def rank_2d_int64(object in_arr, axis=0, ties_method='average',
362377 """
363378
364379 cdef:
365- Py_ssize_t i, j, z, k, n, dups = 0
380+ Py_ssize_t i, j, z, k, n, dups = 0 , total_tie_count = 0
366381 ndarray[float64_t, ndim= 2 ] ranks
367382 ndarray[int64_t, ndim= 2 ] argsorted
368383 ndarray[int64_t, ndim= 2 , cast= True ] values
@@ -395,6 +410,7 @@ def rank_2d_int64(object in_arr, axis=0, ties_method='average',
395410
396411 for i in range (n):
397412 dups = sum_ranks = 0
413+ total_tie_count = 0
398414 for j in range (k):
399415 sum_ranks += j + 1
400416 dups += 1
@@ -415,6 +431,10 @@ def rank_2d_int64(object in_arr, axis=0, ties_method='average',
415431 elif tiebreak == TIEBREAK_FIRST_DESCENDING:
416432 for z in range (j - dups + 1 , j + 1 ):
417433 ranks[i, argsorted[i, z]] = 2 * j - z - dups + 2
434+ elif tiebreak == TIEBREAK_DENSE:
435+ total_tie_count += 1
436+ for z in range (j - dups + 1 , j + 1 ):
437+ ranks[i, argsorted[i, z]] = total_tie_count
418438 sum_ranks = dups = 0
419439
420440 if axis == 0 :
@@ -430,7 +450,7 @@ def rank_1d_generic(object in_arr, bint retry=1, ties_method='average',
430450 """
431451
432452 cdef:
433- Py_ssize_t i, j, n, dups = 0
453+ Py_ssize_t i, j, n, dups = 0 , total_tie_count = 0
434454 ndarray[float64_t] ranks
435455 ndarray sorted_data, values
436456 ndarray[int64_t] argsorted
@@ -502,6 +522,10 @@ def rank_1d_generic(object in_arr, bint retry=1, ties_method='average',
502522 ranks[argsorted[j]] = i + 1
503523 elif tiebreak == TIEBREAK_FIRST:
504524 raise ValueError (' first not supported for non-numeric data' )
525+ elif tiebreak == TIEBREAK_DENSE:
526+ total_tie_count += 1
527+ for j in range (i - dups + 1 , i + 1 ):
528+ ranks[argsorted[j]] = total_tie_count
505529 sum_ranks = dups = 0
506530 if pct:
507531 ranks / count
@@ -545,6 +569,7 @@ def rank_2d_generic(object in_arr, axis=0, ties_method='average',
545569
546570 cdef:
547571 Py_ssize_t i, j, z, k, n, infs, dups = 0
572+ Py_ssize_t total_tie_count = 0
548573 ndarray[float64_t, ndim= 2 ] ranks
549574 ndarray[object , ndim= 2 ] values
550575 ndarray[int64_t, ndim= 2 ] argsorted
@@ -600,6 +625,7 @@ def rank_2d_generic(object in_arr, axis=0, ties_method='average',
600625
601626 for i in range (n):
602627 dups = sum_ranks = infs = 0
628+ total_tie_count = 0
603629 for j in range (k):
604630 val = values[i, j]
605631 if val is nan_value and keep_na:
@@ -621,6 +647,10 @@ def rank_2d_generic(object in_arr, axis=0, ties_method='average',
621647 elif tiebreak == TIEBREAK_FIRST:
622648 raise ValueError (' first not supported for '
623649 ' non-numeric data' )
650+ elif tiebreak == TIEBREAK_DENSE:
651+ total_tie_count += 1
652+ for z in range (j - dups + 1 , j + 1 ):
653+ ranks[i, argsorted[i, z]] = total_tie_count
624654 sum_ranks = dups = 0
625655
626656 if axis == 0 :
0 commit comments