diff --git a/pandas/_libs/hashtable_func_helper.pxi.in b/pandas/_libs/hashtable_func_helper.pxi.in index 6f18ea111db50..5b6152a81a5bf 100644 --- a/pandas/_libs/hashtable_func_helper.pxi.in +++ b/pandas/_libs/hashtable_func_helper.pxi.in @@ -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}} @@ -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: