From 6711b9771a48419689a8fc77ba0b47aaecc67430 Mon Sep 17 00:00:00 2001 From: gfyoung Date: Wed, 21 Dec 2016 03:00:58 -0500 Subject: [PATCH] MAINT: Abstract index helpers in pxi.in file --- pandas/index.pyx | 129 +-------------------------- pandas/src/index_class_helper.pxi.in | 90 +++++++++++++++++++ setup.py | 1 + 3 files changed, 95 insertions(+), 125 deletions(-) create mode 100644 pandas/src/index_class_helper.pxi.in diff --git a/pandas/index.pyx b/pandas/index.pyx index a245e85d80f96..d575defe17422 100644 --- a/pandas/index.pyx +++ b/pandas/index.pyx @@ -363,115 +363,6 @@ cdef class IndexEngine: return result[0:count], missing[0:count_missing] -cdef class Int64Engine(IndexEngine): - - cdef _get_index_values(self): - return algos.ensure_int64(self.vgetter()) - - cdef _make_hash_table(self, n): - return _hash.Int64HashTable(n) - - def _call_monotonic(self, values): - return algos.is_monotonic_int64(values, timelike=False) - - def get_pad_indexer(self, other, limit=None): - return algos.pad_int64(self._get_index_values(), other, - limit=limit) - - def get_backfill_indexer(self, other, limit=None): - return algos.backfill_int64(self._get_index_values(), other, - limit=limit) - - cdef _check_type(self, object val): - hash(val) - if util.is_bool_object(val): - raise KeyError(val) - elif util.is_float_object(val): - raise KeyError(val) - - cdef _maybe_get_bool_indexer(self, object val): - cdef: - ndarray[uint8_t, cast=True] indexer - ndarray[int64_t] values - int count = 0 - Py_ssize_t i, n - int64_t ival - int last_true - - if not util.is_integer_object(val): - raise KeyError(val) - - ival = val - - values = self._get_index_values() - n = len(values) - - result = np.empty(n, dtype=bool) - indexer = result.view(np.uint8) - - for i in range(n): - if values[i] == val: - count += 1 - indexer[i] = 1 - last_true = i - else: - indexer[i] = 0 - - if count == 0: - raise KeyError(val) - if count == 1: - return last_true - - return result - -cdef class Float64Engine(IndexEngine): - - cdef _make_hash_table(self, n): - return _hash.Float64HashTable(n) - - cdef _get_index_values(self): - return algos.ensure_float64(self.vgetter()) - - cdef _maybe_get_bool_indexer(self, object val): - cdef: - ndarray[uint8_t] indexer - ndarray[float64_t] values - int count = 0 - Py_ssize_t i, n - int last_true - - values = self._get_index_values() - n = len(values) - - result = np.empty(n, dtype=bool) - indexer = result.view(np.uint8) - - for i in range(n): - if values[i] == val: - count += 1 - indexer[i] = 1 - last_true = i - else: - indexer[i] = 0 - - if count == 0: - raise KeyError(val) - if count == 1: - return last_true - - return result - - def _call_monotonic(self, values): - return algos.is_monotonic_float64(values, timelike=False) - - def get_pad_indexer(self, other, limit=None): - return algos.pad_float64(self._get_index_values(), other, - limit=limit) - - def get_backfill_indexer(self, other, limit=None): - return algos.backfill_float64(self._get_index_values(), other, - limit=limit) - cdef Py_ssize_t _bin_search(ndarray values, object val) except -1: cdef: @@ -510,22 +401,6 @@ _backfill_functions = { 'float64': algos.backfill_float64 } -cdef class ObjectEngine(IndexEngine): - - cdef _make_hash_table(self, n): - return _hash.PyObjectHashTable(n) - - def _call_monotonic(self, values): - return algos.is_monotonic_object(values, timelike=False) - - def get_pad_indexer(self, other, limit=None): - return algos.pad_object(self._get_index_values(), other, - limit=limit) - - def get_backfill_indexer(self, other, limit=None): - return algos.backfill_object(self._get_index_values(), other, - limit=limit) - cdef class DatetimeEngine(Int64Engine): @@ -668,3 +543,7 @@ cdef inline _to_i8(object val): cdef inline bint _is_utc(object tz): return tz is UTC or isinstance(tz, _du_utc) + + +# Generated from template. +include "index_class_helper.pxi" diff --git a/pandas/src/index_class_helper.pxi.in b/pandas/src/index_class_helper.pxi.in new file mode 100644 index 0000000000000..315dd18009ad4 --- /dev/null +++ b/pandas/src/index_class_helper.pxi.in @@ -0,0 +1,90 @@ +""" +Template for functions of IndexEngine subclasses. + +WARNING: DO NOT edit .pxi FILE directly, .pxi is generated from .pxi.in +""" + +#---------------------------------------------------------------------- +# IndexEngine Subclass Methods +#---------------------------------------------------------------------- + +{{py: + +# name, dtype, ctype +dtypes = [('Float64', 'float64', 'float64_t'), + ('Int64', 'int64', 'int64_t'), + ('Object', 'object', 'object')] +}} + +{{for name, dtype, ctype in dtypes}} + + +cdef class {{name}}Engine(IndexEngine): + + def _call_monotonic(self, values): + return algos.is_monotonic_{{dtype}}(values, timelike=False) + + def get_backfill_indexer(self, other, limit=None): + return algos.backfill_{{dtype}}(self._get_index_values(), + other, limit=limit) + + def get_pad_indexer(self, other, limit=None): + return algos.pad_{{dtype}}(self._get_index_values(), + other, limit=limit) + + cdef _make_hash_table(self, n): + {{if name == 'Object'}} + return _hash.PyObjectHashTable(n) + {{else}} + return _hash.{{name}}HashTable(n) + {{endif}} + + {{if name != 'Float64' and name != 'Object'}} + cdef _check_type(self, object val): + hash(val) + if util.is_bool_object(val): + raise KeyError(val) + elif util.is_float_object(val): + raise KeyError(val) + {{endif}} + + {{if name != 'Object'}} + cdef _get_index_values(self): + return algos.ensure_{{dtype}}(self.vgetter()) + + cdef _maybe_get_bool_indexer(self, object val): + cdef: + ndarray[uint8_t, cast=True] indexer + ndarray[{{ctype}}] values + int count = 0 + Py_ssize_t i, n + int last_true + + {{if name != 'Float64'}} + if not util.is_integer_object(val): + raise KeyError(val) + {{endif}} + + values = self._get_index_values() + n = len(values) + + result = np.empty(n, dtype=bool) + indexer = result.view(np.uint8) + + for i in range(n): + if values[i] == val: + count += 1 + indexer[i] = 1 + last_true = i + else: + indexer[i] = 0 + + if count == 0: + raise KeyError(val) + if count == 1: + return last_true + + return result + {{endif}} + +{{endfor}} diff --git a/setup.py b/setup.py index 0821a7d907e6c..0a84cf527bfb1 100755 --- a/setup.py +++ b/setup.py @@ -116,6 +116,7 @@ def is_platform_mac(): '_join': ['join_helper.pxi.in', 'joins_func_helper.pxi.in'], 'hashtable': ['hashtable_class_helper.pxi.in', 'hashtable_func_helper.pxi.in'], + 'index': ['index_class_helper.pxi.in'], '_sparse': ['sparse_op_helper.pxi.in'] } _pxifiles = []