@@ -44,6 +44,10 @@ def rank_1d_{{dtype}}(object in_arr, ties_method='average', ascending=True,
4444
4545 {{if dtype == 'object'}}
4646 ndarray sorted_data, values
47+ ndarray[np.uint8_t, cast=True] sorted_namask
48+ {{elif dtype != 'uint64'}}
49+ ndarray[{{ctype}}] sorted_data, values
50+ ndarray[np.uint8_t, cast=True] sorted_namask
4751 {{else}}
4852 ndarray[{{ctype}}] sorted_data, values
4953 {{endif}}
@@ -54,7 +58,7 @@ def rank_1d_{{dtype}}(object in_arr, ties_method='average', ascending=True,
5458 {{if dtype == 'uint64'}}
5559 {{ctype}} val
5660 {{else}}
57- {{ctype}} val, nan_value
61+ {{ctype}} val, nan_value, isnan
5862 {{endif}}
5963
6064 float64_t sum_ranks = 0
@@ -123,17 +127,23 @@ def rank_1d_{{dtype}}(object in_arr, ties_method='average', ascending=True,
123127 _as = _as[::-1]
124128
125129 sorted_data = values.take(_as)
130+ # need to distinguish between pos/neg nan and real nan when keep_na is true
131+ {{if dtype != 'uint64'}}
132+ sorted_namask = mask.take(_as)
133+ sorted_namask = sorted_namask.astype(np.bool)
134+ {{endif}}
126135 argsorted = _as.astype('i8')
127136
128137 {{if dtype == 'object'}}
129138 for i in range(n):
130139 sum_ranks += i + 1
131140 dups += 1
132-
141+ isnan = sorted_namask[i]
133142 val = util.get_value_at(sorted_data, i)
134143
135- if (val is nan_value) and keep_na:
144+ if isnan and keep_na:
136145 ranks[argsorted[i]] = nan
146+ sum_ranks = dups = 0
137147 continue
138148
139149 count += 1.0
@@ -168,8 +178,10 @@ def rank_1d_{{dtype}}(object in_arr, ties_method='average', ascending=True,
168178 val = sorted_data[i]
169179
170180 {{if dtype != 'uint64'}}
171- if (val == nan_value) and keep_na:
181+ isnan = sorted_namask[i]
182+ if isnan and keep_na:
172183 ranks[argsorted[i]] = nan
184+ sum_ranks = dups = 0
173185 continue
174186 {{endif}}
175187
0 commit comments