Skip to content

REF: use fused types for mode #46089

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 26, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 39 additions & 85 deletions pandas/_libs/hashtable_func_helper.pxi.in
Original file line number Diff line number Diff line change
Expand Up @@ -247,63 +247,6 @@ cdef ismember_{{dtype}}(const {{dtype}}_t[:] arr, const {{dtype}}_t[:] values):
# Mode Computations
# ----------------------------------------------------------------------


@cython.wraparound(False)
@cython.boundscheck(False)
{{if dtype == 'object'}}
cdef mode_{{dtype}}(ndarray[{{dtype}}] values, bint dropna):
{{else}}
cdef mode_{{dtype}}(const {{dtype}}_t[:] values, bint dropna):
{{endif}}
cdef:
{{if dtype == 'object'}}
ndarray[{{dtype}}] keys
ndarray[{{dtype}}] modes
{{else}}
{{dtype}}_t[:] keys
ndarray[{{dtype}}_t] modes
{{endif}}
int64_t[:] counts
int64_t count, max_count = -1
Py_ssize_t k, j = 0

keys, counts = value_count_{{dtype}}(values, dropna)

{{if dtype == 'object'}}
modes = np.empty(len(keys), dtype=np.object_)
{{else}}
modes = np.empty(len(keys), dtype=np.{{dtype}})
{{endif}}

{{if dtype != 'object'}}
with nogil:
for k in range(len(keys)):
count = counts[k]
if count == max_count:
j += 1
elif count > max_count:
max_count = count
j = 0
else:
continue

modes[j] = keys[k]
{{else}}
for k in range(len(keys)):
count = counts[k]
if count == max_count:
j += 1
elif count > max_count:
max_count = count
j = 0
else:
continue

modes[j] = keys[k]
{{endif}}

return modes[:j + 1]

{{endfor}}


Expand Down Expand Up @@ -431,40 +374,51 @@ cpdef ismember(ndarray[htfunc_t] arr, ndarray[htfunc_t] values):
raise TypeError(values.dtype)


cpdef mode(ndarray[htfunc_t] values, bint dropna):
if htfunc_t is object:
return mode_object(values, dropna)
@cython.wraparound(False)
@cython.boundscheck(False)
def mode(ndarray[htfunc_t] values, bint dropna):
# TODO(cython3): use const htfunct_t[:]

elif htfunc_t is int8_t:
return mode_int8(values, dropna)
elif htfunc_t is int16_t:
return mode_int16(values, dropna)
elif htfunc_t is int32_t:
return mode_int32(values, dropna)
elif htfunc_t is int64_t:
return mode_int64(values, dropna)
cdef:
ndarray[htfunc_t] keys
ndarray[htfunc_t] modes

elif htfunc_t is uint8_t:
return mode_uint8(values, dropna)
elif htfunc_t is uint16_t:
return mode_uint16(values, dropna)
elif htfunc_t is uint32_t:
return mode_uint32(values, dropna)
elif htfunc_t is uint64_t:
return mode_uint64(values, dropna)
int64_t[:] counts
int64_t count, max_count = -1
Py_ssize_t nkeys, k, j = 0

elif htfunc_t is float64_t:
return mode_float64(values, dropna)
elif htfunc_t is float32_t:
return mode_float32(values, dropna)
keys, counts = value_count(values, dropna)
nkeys = len(keys)

elif htfunc_t is complex128_t:
return mode_complex128(values, dropna)
elif htfunc_t is complex64_t:
return mode_complex64(values, dropna)
modes = np.empty(nkeys, dtype=values.dtype)

if htfunc_t is not object:
with nogil:
for k in range(nkeys):
count = counts[k]
if count == max_count:
j += 1
elif count > max_count:
max_count = count
j = 0
else:
continue

modes[j] = keys[k]
else:
raise TypeError(values.dtype)
for k in range(nkeys):
count = counts[k]
if count == max_count:
j += 1
elif count > max_count:
max_count = count
j = 0
else:
continue

modes[j] = keys[k]

return modes[:j + 1]


{{py:
Expand Down