Skip to content

Commit

Permalink
REF: use fused types for mode (pandas-dev#46089)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrockmendel authored Feb 26, 2022
1 parent 443f2b1 commit 3b946d3
Showing 1 changed file with 39 additions and 85 deletions.
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 @@ -240,63 +240,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 @@ -414,40 +357,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

0 comments on commit 3b946d3

Please sign in to comment.