diff --git a/pandas/_libs/algos.pyx b/pandas/_libs/algos.pyx index 3ba4c2375b4e8..02815dce156fb 100644 --- a/pandas/_libs/algos.pyx +++ b/pandas/_libs/algos.pyx @@ -77,6 +77,8 @@ class NegInfinity(object): __ge__ = lambda self, other: isinstance(other, NegInfinity) +@cython.wraparound(False) +@cython.boundscheck(False) cpdef ndarray[int64_t, ndim=1] unique_deltas(ndarray[int64_t] arr): """ Efficiently find the unique first-differences of the given array. @@ -793,7 +795,7 @@ arrmap_bool = arrmap["uint8_t"] @cython.boundscheck(False) @cython.wraparound(False) -def is_monotonic(ndarray[algos_t] arr, bint timelike): +def is_monotonic(ndarray[algos_t, ndim=1] arr, bint timelike): """ Returns ------- diff --git a/pandas/_libs/groupby.pyx b/pandas/_libs/groupby.pyx index d683c93c9b32e..2894e014b84b8 100644 --- a/pandas/_libs/groupby.pyx +++ b/pandas/_libs/groupby.pyx @@ -353,7 +353,7 @@ def group_any_all(ndarray[uint8_t] out, The returned values will either be 0 or 1 (False or True, respectively). """ cdef: - Py_ssize_t i, N=len(labels) + Py_ssize_t i, N = len(labels) int64_t lab uint8_t flag_val diff --git a/pandas/_libs/groupby_helper.pxi.in b/pandas/_libs/groupby_helper.pxi.in index 335c8ee5c2340..315cfea56896e 100644 --- a/pandas/_libs/groupby_helper.pxi.in +++ b/pandas/_libs/groupby_helper.pxi.in @@ -667,11 +667,6 @@ def group_max(ndarray[groupby_t, ndim=2] out, out[i, j] = maxx[i, j] -group_max_float64 = group_max["float64_t"] -group_max_float32 = group_max["float32_t"] -group_max_int64 = group_max["int64_t"] - - @cython.wraparound(False) @cython.boundscheck(False) def group_min(ndarray[groupby_t, ndim=2] out, @@ -734,11 +729,6 @@ def group_min(ndarray[groupby_t, ndim=2] out, out[i, j] = minx[i, j] -group_min_float64 = group_min["float64_t"] -group_min_float32 = group_min["float32_t"] -group_min_int64 = group_min["int64_t"] - - @cython.boundscheck(False) @cython.wraparound(False) def group_cummin(ndarray[groupby_t, ndim=2] out, @@ -787,11 +777,6 @@ def group_cummin(ndarray[groupby_t, ndim=2] out, out[i, j] = mval -group_cummin_float64 = group_cummin["float64_t"] -group_cummin_float32 = group_cummin["float32_t"] -group_cummin_int64 = group_cummin["int64_t"] - - @cython.boundscheck(False) @cython.wraparound(False) def group_cummax(ndarray[groupby_t, ndim=2] out, @@ -837,8 +822,3 @@ def group_cummax(ndarray[groupby_t, ndim=2] out, if val > mval: accum[lab, j] = mval = val out[i, j] = mval - - -group_cummax_float64 = group_cummax["float64_t"] -group_cummax_float32 = group_cummax["float32_t"] -group_cummax_int64 = group_cummax["int64_t"] diff --git a/pandas/_libs/hashtable_class_helper.pxi.in b/pandas/_libs/hashtable_class_helper.pxi.in index 27758234c0cf1..1fdd8e3b1987f 100644 --- a/pandas/_libs/hashtable_class_helper.pxi.in +++ b/pandas/_libs/hashtable_class_helper.pxi.in @@ -86,12 +86,12 @@ cdef class {{name}}Vector: self.data.n = 0 self.data.m = _INIT_VEC_CAP self.ao = np.empty(self.data.m, dtype={{idtype}}) - self.data.data = <{{arg}}*> self.ao.data + self.data.data = <{{arg}}*>self.ao.data cdef resize(self): self.data.m = max(self.data.m * 4, _INIT_VEC_CAP) self.ao.resize(self.data.m, refcheck=False) - self.data.data = <{{arg}}*> self.ao.data + self.data.data = <{{arg}}*>self.ao.data def __dealloc__(self): if self.data is not NULL: @@ -140,7 +140,7 @@ cdef class StringVector: self.external_view_exists = False self.data.n = 0 self.data.m = _INIT_VEC_CAP - self.data.data = malloc(self.data.m * sizeof(char *)) + self.data.data = malloc(self.data.m * sizeof(char *)) if not self.data.data: raise MemoryError() @@ -153,7 +153,7 @@ cdef class StringVector: self.data.m = max(self.data.m * 4, _INIT_VEC_CAP) orig_data = self.data.data - self.data.data = malloc(self.data.m * sizeof(char *)) + self.data.data = malloc(self.data.m * sizeof(char *)) if not self.data.data: raise MemoryError() for i in range(m): @@ -208,22 +208,22 @@ cdef class ObjectVector: self.n = 0 self.m = _INIT_VEC_CAP self.ao = np.empty(_INIT_VEC_CAP, dtype=object) - self.data = self.ao.data + self.data = self.ao.data def __len__(self): return self.n - cdef inline append(self, object o): + cdef inline append(self, object obj): if self.n == self.m: if self.external_view_exists: raise ValueError("external reference but " "Vector.resize() needed") self.m = max(self.m * 2, _INIT_VEC_CAP) self.ao.resize(self.m, refcheck=False) - self.data = self.ao.data + self.data = self.ao.data - Py_INCREF(o) - self.data[self.n] = o + Py_INCREF(obj) + self.data[self.n] = obj self.n += 1 def to_array(self): @@ -768,7 +768,7 @@ cdef class StringHashTable(HashTable): use_na_value = na_value is not None # assign pointers and pre-filter out missing - vecs = malloc(n * sizeof(char *)) + vecs = malloc(n * sizeof(char *)) for i in range(n): val = values[i] @@ -844,9 +844,9 @@ cdef class PyObjectHashTable(HashTable): def sizeof(self, deep=False): """ return the size of my table in bytes """ - return self.table.n_buckets * (sizeof(PyObject *) + # keys - sizeof(Py_ssize_t) + # vals - sizeof(uint32_t)) # flags + return self.table.n_buckets * (sizeof(PyObject *) + # keys + sizeof(Py_ssize_t) + # vals + sizeof(uint32_t)) # flags cpdef get_item(self, object val): cdef khiter_t k diff --git a/pandas/_libs/hashtable_func_helper.pxi.in b/pandas/_libs/hashtable_func_helper.pxi.in index 801c67832d8b9..80d864c65d087 100644 --- a/pandas/_libs/hashtable_func_helper.pxi.in +++ b/pandas/_libs/hashtable_func_helper.pxi.in @@ -45,11 +45,11 @@ cdef build_count_table_{{dtype}}({{dtype}}_t[:] values, val = values[i] if not checknull(val) or not dropna: - k = kh_get_{{ttype}}(table, val) + k = kh_get_{{ttype}}(table, val) if k != table.n_buckets: table.vals[k] += 1 else: - k = kh_put_{{ttype}}(table, val, &ret) + k = kh_put_{{ttype}}(table, val, &ret) table.vals[k] = 1 {{else}} with nogil: @@ -103,7 +103,7 @@ cpdef value_count_{{dtype}}({{scalar}}[:] values, bint dropna): {{if dtype == 'object'}} for k in range(table.n_buckets): if kh_exist_{{ttype}}(table, k): - result_keys[i] = <{{dtype}}> table.keys[k] + result_keys[i] = <{{dtype}}>table.keys[k] result_counts[i] = table.vals[k] i += 1 {{else}} @@ -152,7 +152,7 @@ def duplicated_{{dtype}}({{scalar}}[:] values, object keep='first'): if keep == 'last': {{if dtype == 'object'}} for i from n > i >= 0: - kh_put_{{ttype}}(table, values[i], &ret) + kh_put_{{ttype}}(table, values[i], &ret) out[i] = ret == 0 {{else}} with nogil: @@ -163,7 +163,7 @@ def duplicated_{{dtype}}({{scalar}}[:] values, object keep='first'): elif keep == 'first': {{if dtype == 'object'}} for i in range(n): - kh_put_{{ttype}}(table, values[i], &ret) + kh_put_{{ttype}}(table, values[i], &ret) out[i] = ret == 0 {{else}} with nogil: @@ -175,13 +175,13 @@ def duplicated_{{dtype}}({{scalar}}[:] values, object keep='first'): {{if dtype == 'object'}} for i in range(n): value = values[i] - k = kh_get_{{ttype}}(table, value) + k = kh_get_{{ttype}}(table, value) if k != table.n_buckets: out[table.vals[k]] = 1 out[i] = 1 else: - k = kh_put_{{ttype}}(table, value, &ret) - table.keys[k] = value + k = kh_put_{{ttype}}(table, value, &ret) + table.keys[k] = value table.vals[k] = i out[i] = 0 {{else}} @@ -245,7 +245,7 @@ def ismember_{{dtype}}({{scalar}}[:] arr, {{scalar}}[:] values): {{if dtype == 'object'}} for i in range(n): - kh_put_{{ttype}}(table, values[i], &ret) + kh_put_{{ttype}}(table, values[i], &ret) {{else}} with nogil: for i in range(n): @@ -259,7 +259,7 @@ def ismember_{{dtype}}({{scalar}}[:] arr, {{scalar}}[:] values): {{if dtype == 'object'}} for i in range(n): val = arr[i] - k = kh_get_{{ttype}}(table, val) + k = kh_get_{{ttype}}(table, val) result[i] = (k != table.n_buckets) {{else}} with nogil: @@ -342,7 +342,7 @@ def mode_{{dtype}}({{ctype}}[:] values, bint dropna): else: continue - modes[j] = table.keys[k] + modes[j] = table.keys[k] {{endif}} kh_destroy_{{table_type}}(table) diff --git a/pandas/_libs/join.pyx b/pandas/_libs/join.pyx index c6afeda6a37dc..c92e0a4a7aa23 100644 --- a/pandas/_libs/join.pyx +++ b/pandas/_libs/join.pyx @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- -cimport cython -from cython cimport Py_ssize_t +import cython +from cython import Py_ssize_t import numpy as np cimport numpy as cnp diff --git a/pandas/_libs/lib.pyx b/pandas/_libs/lib.pyx index 6ec9a7e93bc55..c57dd66a33fe0 100644 --- a/pandas/_libs/lib.pyx +++ b/pandas/_libs/lib.pyx @@ -18,7 +18,7 @@ PyDateTime_IMPORT import numpy as np cimport numpy as cnp -from numpy cimport (ndarray, PyArray_NDIM, PyArray_GETITEM, +from numpy cimport (ndarray, PyArray_GETITEM, PyArray_ITER_DATA, PyArray_ITER_NEXT, PyArray_IterNew, flatiter, NPY_OBJECT, int64_t, @@ -74,9 +74,9 @@ cdef bint PY2 = sys.version_info[0] == 2 cdef double nan = np.NaN -def values_from_object(object obj): +def values_from_object(obj: object): """ return my values or the object if we are say an ndarray """ - cdef func # TODO: Does declaring this without a type accomplish anything? + func: object func = getattr(obj, 'get_values', None) if func is not None: @@ -195,7 +195,7 @@ def fast_unique_multiple(list arrays): @cython.wraparound(False) @cython.boundscheck(False) -def fast_unique_multiple_list(list lists, bint sort=True): +def fast_unique_multiple_list(lists: list, sort: bool=True) -> list: cdef: list buf Py_ssize_t k = len(lists) @@ -263,7 +263,7 @@ def fast_unique_multiple_list_gen(object gen, bint sort=True): @cython.wraparound(False) @cython.boundscheck(False) -def dicts_to_array(list dicts, list columns): +def dicts_to_array(dicts: list, columns: list): cdef: Py_ssize_t i, j, k, n ndarray[object, ndim=2] result @@ -356,7 +356,9 @@ def get_reverse_indexer(ndarray[int64_t] indexer, Py_ssize_t length): return rev_indexer -def has_infs_f4(ndarray[float32_t] arr) -> bint: +@cython.wraparound(False) +@cython.boundscheck(False) +def has_infs_f4(ndarray[float32_t] arr) -> bool: cdef: Py_ssize_t i, n = len(arr) float32_t inf, neginf, val @@ -371,7 +373,9 @@ def has_infs_f4(ndarray[float32_t] arr) -> bint: return False -def has_infs_f8(ndarray[float64_t] arr) -> bint: +@cython.wraparound(False) +@cython.boundscheck(False) +def has_infs_f8(ndarray[float64_t] arr) -> bool: cdef: Py_ssize_t i, n = len(arr) float64_t inf, neginf, val @@ -423,6 +427,8 @@ def maybe_indices_to_slice(ndarray[int64_t] indices, int max_len): return slice(vstart, vlast - 1, k) +@cython.wraparound(False) +@cython.boundscheck(False) def maybe_booleans_to_slice(ndarray[uint8_t] mask): cdef: Py_ssize_t i, n = len(mask) @@ -454,7 +460,7 @@ def maybe_booleans_to_slice(ndarray[uint8_t] mask): @cython.wraparound(False) @cython.boundscheck(False) -def array_equivalent_object(left: object[:], right: object[:]) -> bint: +def array_equivalent_object(left: object[:], right: object[:]) -> bool: """ perform an element by element comparion on 1-d object arrays taking into account nan positions """ cdef: @@ -478,7 +484,7 @@ def array_equivalent_object(left: object[:], right: object[:]) -> bint: def astype_intsafe(ndarray[object] arr, new_dtype): cdef: Py_ssize_t i, n = len(arr) - object v + object val bint is_datelike ndarray result @@ -487,19 +493,18 @@ def astype_intsafe(ndarray[object] arr, new_dtype): result = np.empty(n, dtype=new_dtype) for i in range(n): - v = arr[i] - if is_datelike and checknull(v): + val = arr[i] + if is_datelike and checknull(val): result[i] = NPY_NAT else: - result[i] = v + result[i] = val return result @cython.wraparound(False) @cython.boundscheck(False) -def astype_unicode(arr: ndarray, - skipna: bool=False) -> ndarray[object]: +def astype_unicode(arr: ndarray, skipna: bool=False) -> ndarray[object]: """ Convert all elements in an array to unicode. @@ -534,8 +539,7 @@ def astype_unicode(arr: ndarray, @cython.wraparound(False) @cython.boundscheck(False) -def astype_str(arr: ndarray, - skipna: bool=False) -> ndarray[object]: +def astype_str(arr: ndarray, skipna: bool=False) -> ndarray[object]: """ Convert all elements in an array to string. @@ -570,19 +574,19 @@ def astype_str(arr: ndarray, @cython.wraparound(False) @cython.boundscheck(False) -def clean_index_list(list obj): +def clean_index_list(obj: list): """ Utility used in pandas.core.index.ensure_index """ cdef: Py_ssize_t i, n = len(obj) - object v + object val bint all_arrays = 1 for i in range(n): - v = obj[i] - if not (isinstance(v, list) or - util.is_array(v) or hasattr(v, '_data')): + val = obj[i] + if not (isinstance(val, list) or + util.is_array(val) or hasattr(val, '_data')): all_arrays = 0 break @@ -594,7 +598,7 @@ def clean_index_list(list obj): if inferred in ['string', 'bytes', 'unicode', 'mixed', 'mixed-integer']: return np.asarray(obj, dtype=object), 0 elif inferred in ['integer']: - # TODO: we infer an integer but it *could* be a unint64 + # TODO: we infer an integer but it *could* be a uint64 try: return np.asarray(obj, dtype='int64'), 0 except OverflowError: @@ -680,7 +684,7 @@ def row_bool_subset(ndarray[float64_t, ndim=2] values, Py_ssize_t i, j, n, k, pos = 0 ndarray[float64_t, ndim=2] out - n, k = ( values).shape + n, k = (values).shape assert (n == len(mask)) out = np.empty((mask.sum(), k), dtype=np.float64) @@ -702,7 +706,7 @@ def row_bool_subset_object(ndarray[object, ndim=2] values, Py_ssize_t i, j, n, k, pos = 0 ndarray[object, ndim=2] out - n, k = ( values).shape + n, k = (values).shape assert (n == len(mask)) out = np.empty((mask.sum(), k), dtype=object) @@ -750,7 +754,7 @@ def count_level_2d(ndarray[uint8_t, ndim=2, cast=True] mask, ndarray[int64_t, ndim=2] counts assert (axis == 0 or axis == 1) - n, k = ( mask).shape + n, k = (mask).shape if axis == 0: counts = np.zeros((max_bin, k), dtype='i8') @@ -841,19 +845,19 @@ def indices_fast(object index, ndarray[int64_t] labels, list keys, # core.common import for fast inference checks -def is_float(obj: object) -> bint: +def is_float(obj: object) -> bool: return util.is_float_object(obj) -def is_integer(obj: object) -> bint: +def is_integer(obj: object) -> bool: return util.is_integer_object(obj) -def is_bool(obj: object) -> bint: +def is_bool(obj: object) -> bool: return util.is_bool_object(obj) -def is_complex(obj: object) -> bint: +def is_complex(obj: object) -> bool: return util.is_complex_object(obj) @@ -865,7 +869,7 @@ cpdef bint is_interval(object obj): return getattr(obj, '_typ', '_typ') == 'interval' -def is_period(val: object) -> bint: +def is_period(val: object) -> bool: """ Return a boolean if this is a Period object """ return util.is_period_object(val) @@ -1046,7 +1050,7 @@ cdef _try_infer_map(v): return None -def infer_dtype(object value, bint skipna=False): +def infer_dtype(value: object, skipna: bool=False) -> str: """ Efficiently infer the type of a passed val, or list-like array of values. Return a string describing the type. @@ -1347,7 +1351,7 @@ def infer_datetimelike_array(arr: object) -> object: seen_datetime = 1 elif PyDate_Check(v): seen_date = 1 - elif is_timedelta(v) or util.is_timedelta64_object(v): + elif is_timedelta(v): # timedelta, or timedelta64 seen_timedelta = 1 else: @@ -1626,7 +1630,7 @@ cpdef bint is_datetime64_array(ndarray values): return validator.validate(values) -def is_datetime_with_singletz_array(values: ndarray) -> bint: +def is_datetime_with_singletz_array(values: ndarray) -> bool: """ Check values have the same tzinfo attribute. Doesn't check values are datetime-like types. @@ -2110,6 +2114,8 @@ def maybe_convert_objects(ndarray[object] objects, bint try_float=0, return objects +@cython.boundscheck(False) +@cython.wraparound(False) def map_infer_mask(ndarray arr, object f, ndarray[uint8_t] mask, bint convert=1): """ @@ -2133,11 +2139,11 @@ def map_infer_mask(ndarray arr, object f, ndarray[uint8_t] mask, result = np.empty(n, dtype=object) for i in range(n): if mask[i]: - val = util.get_value_at(arr, i) + val = arr[i] else: - val = f(util.get_value_at(arr, i)) + val = f(arr[i]) - if util.is_array(val) and PyArray_NDIM(val) == 0: + if cnp.PyArray_IsZeroDim(val): # unbox 0-dim arrays, GH#690 # TODO: is there a faster way to unbox? # item_from_zerodim? @@ -2154,6 +2160,8 @@ def map_infer_mask(ndarray arr, object f, ndarray[uint8_t] mask, return result +@cython.boundscheck(False) +@cython.wraparound(False) def map_infer(ndarray arr, object f, bint convert=1): """ Substitute for np.vectorize with pandas-friendly dtype inference @@ -2175,9 +2183,9 @@ def map_infer(ndarray arr, object f, bint convert=1): n = len(arr) result = np.empty(n, dtype=object) for i in range(n): - val = f(util.get_value_at(arr, i)) + val = f(arr[i]) - if util.is_array(val) and PyArray_NDIM(val) == 0: + if cnp.PyArray_IsZeroDim(val): # unbox 0-dim arrays, GH#690 # TODO: is there a faster way to unbox? # item_from_zerodim? @@ -2194,7 +2202,7 @@ def map_infer(ndarray arr, object f, bint convert=1): return result -def to_object_array(list rows, int min_width=0): +def to_object_array(rows: list, min_width: int=0): """ Convert a list of lists into an object array. @@ -2253,7 +2261,7 @@ def tuples_to_object_array(ndarray[object] tuples): return result -def to_object_array_tuples(list rows): +def to_object_array_tuples(rows: list): cdef: Py_ssize_t i, j, n, k, tmp ndarray[object, ndim=2] result @@ -2284,6 +2292,8 @@ def to_object_array_tuples(list rows): return result +@cython.wraparound(False) +@cython.boundscheck(False) def fast_multiget(dict mapping, ndarray keys, default=np.nan): cdef: Py_ssize_t i, n = len(keys) diff --git a/pandas/_libs/tslibs/ccalendar.pyx b/pandas/_libs/tslibs/ccalendar.pyx index 7d58b43e5d460..07c146c06b510 100644 --- a/pandas/_libs/tslibs/ccalendar.pyx +++ b/pandas/_libs/tslibs/ccalendar.pyx @@ -54,7 +54,7 @@ weekday_to_int = {int_to_weekday[key]: key for key in int_to_weekday} @cython.wraparound(False) @cython.boundscheck(False) -cpdef inline int32_t get_days_in_month(int year, Py_ssize_t month) nogil: +cpdef int32_t get_days_in_month(int year, Py_ssize_t month) nogil: """Return the number of days in the given month of the given year. Parameters diff --git a/pandas/_libs/tslibs/conversion.pyx b/pandas/_libs/tslibs/conversion.pyx index d91283deb9fc7..d199997d2e9fe 100644 --- a/pandas/_libs/tslibs/conversion.pyx +++ b/pandas/_libs/tslibs/conversion.pyx @@ -75,7 +75,7 @@ cdef inline int64_t get_datetime64_nanos(object val) except? -1: @cython.boundscheck(False) @cython.wraparound(False) -def ensure_datetime64ns(ndarray arr, copy=True): +def ensure_datetime64ns(arr: ndarray, copy: bool=True): """ Ensure a np.datetime64 array has dtype specifically 'datetime64[ns]' @@ -122,7 +122,7 @@ def ensure_datetime64ns(ndarray arr, copy=True): return result -def ensure_timedelta64ns(ndarray arr, copy=True): +def ensure_timedelta64ns(arr: ndarray, copy: bool=True): """ Ensure a np.timedelta64 array has dtype specifically 'timedelta64[ns]' @@ -137,11 +137,12 @@ def ensure_timedelta64ns(ndarray arr, copy=True): """ return arr.astype(TD_DTYPE, copy=copy) + # TODO: check for overflows when going from a lower-resolution to nanos @cython.boundscheck(False) @cython.wraparound(False) -def datetime_to_datetime64(object[:] values): +def datetime_to_datetime64(values: object[:]): """ Convert ndarray of datetime-like objects to int64 array representing nanosecond timestamps. @@ -614,6 +615,8 @@ cpdef inline datetime localize_pydatetime(datetime dt, object tz): # ---------------------------------------------------------------------- # Timezone Conversion +@cython.boundscheck(False) +@cython.wraparound(False) cdef inline int64_t[:] _tz_convert_dst(int64_t[:] values, tzinfo tz, bint to_utc=True): """ @@ -1220,7 +1223,7 @@ cdef inline int64_t _normalized_stamp(npy_datetimestruct *dts) nogil: @cython.wraparound(False) @cython.boundscheck(False) -def is_date_array_normalized(int64_t[:] stamps, tz=None): +def is_date_array_normalized(int64_t[:] stamps, object tz=None): """ Check if all of the given (nanosecond) timestamps are normalized to midnight, i.e. hour == minute == second == 0. If the optional timezone diff --git a/pandas/_libs/tslibs/fields.pyx b/pandas/_libs/tslibs/fields.pyx index 216128cae2002..4c0af69d72517 100644 --- a/pandas/_libs/tslibs/fields.pyx +++ b/pandas/_libs/tslibs/fields.pyx @@ -114,7 +114,7 @@ def get_date_name_field(int64_t[:] dtindex, object field, object locale=None): dt64_to_dtstruct(dtindex[i], &dts) dow = dayofweek(dts.year, dts.month, dts.day) out[i] = names[dow].capitalize() - return out + elif field == 'month_name': if locale is None: names = np.array(MONTHS_FULL, dtype=np.object_) @@ -128,12 +128,15 @@ def get_date_name_field(int64_t[:] dtindex, object field, object locale=None): dt64_to_dtstruct(dtindex[i], &dts) out[i] = names[dts.month].capitalize() - return out - raise ValueError("Field %s not supported" % field) + else: + raise ValueError("Field {field} not supported".format(field=field)) + + return out @cython.wraparound(False) +@cython.boundscheck(False) def get_start_end_field(int64_t[:] dtindex, object field, object freqstr=None, int month_kw=12): """ @@ -163,8 +166,8 @@ def get_start_end_field(int64_t[:] dtindex, object field, if freqstr: if freqstr == 'C': - raise ValueError( - "Custom business days is not supported by %s" % field) + raise ValueError("Custom business days is not supported by {field}" + .format(field=field)) is_business = freqstr[0] == 'B' # YearBegin(), BYearBegin() use month = starting month of year. @@ -196,7 +199,7 @@ def get_start_end_field(int64_t[:] dtindex, object field, if (dom == 1 and dow < 5) or (dom <= 3 and dow == 0): out[i] = 1 - return out.view(bool) + else: for i in range(count): if dtindex[i] == NPY_NAT: @@ -208,7 +211,6 @@ def get_start_end_field(int64_t[:] dtindex, object field, if dom == 1: out[i] = 1 - return out.view(bool) elif field == 'is_month_end': if is_business: @@ -228,7 +230,7 @@ def get_start_end_field(int64_t[:] dtindex, object field, if (ldom == doy and dow < 5) or ( dow == 4 and (ldom - doy <= 2)): out[i] = 1 - return out.view(bool) + else: for i in range(count): if dtindex[i] == NPY_NAT: @@ -244,7 +246,6 @@ def get_start_end_field(int64_t[:] dtindex, object field, if ldom == doy: out[i] = 1 - return out.view(bool) elif field == 'is_quarter_start': if is_business: @@ -260,7 +261,7 @@ def get_start_end_field(int64_t[:] dtindex, object field, if ((dts.month - start_month) % 3 == 0) and ( (dom == 1 and dow < 5) or (dom <= 3 and dow == 0)): out[i] = 1 - return out.view(bool) + else: for i in range(count): if dtindex[i] == NPY_NAT: @@ -272,7 +273,6 @@ def get_start_end_field(int64_t[:] dtindex, object field, if ((dts.month - start_month) % 3 == 0) and dom == 1: out[i] = 1 - return out.view(bool) elif field == 'is_quarter_end': if is_business: @@ -293,7 +293,7 @@ def get_start_end_field(int64_t[:] dtindex, object field, (ldom == doy and dow < 5) or ( dow == 4 and (ldom - doy <= 2))): out[i] = 1 - return out.view(bool) + else: for i in range(count): if dtindex[i] == NPY_NAT: @@ -309,7 +309,6 @@ def get_start_end_field(int64_t[:] dtindex, object field, if ((dts.month - end_month) % 3 == 0) and (ldom == doy): out[i] = 1 - return out.view(bool) elif field == 'is_year_start': if is_business: @@ -325,7 +324,7 @@ def get_start_end_field(int64_t[:] dtindex, object field, if (dts.month == start_month) and ( (dom == 1 and dow < 5) or (dom <= 3 and dow == 0)): out[i] = 1 - return out.view(bool) + else: for i in range(count): if dtindex[i] == NPY_NAT: @@ -337,7 +336,6 @@ def get_start_end_field(int64_t[:] dtindex, object field, if (dts.month == start_month) and dom == 1: out[i] = 1 - return out.view(bool) elif field == 'is_year_end': if is_business: @@ -358,7 +356,7 @@ def get_start_end_field(int64_t[:] dtindex, object field, (ldom == doy and dow < 5) or ( dow == 4 and (ldom - doy <= 2))): out[i] = 1 - return out.view(bool) + else: for i in range(count): if dtindex[i] == NPY_NAT: @@ -374,9 +372,11 @@ def get_start_end_field(int64_t[:] dtindex, object field, if (dts.month == end_month) and (ldom == doy): out[i] = 1 - return out.view(bool) - raise ValueError("Field %s not supported" % field) + else: + raise ValueError("Field {field} not supported".format(field=field)) + + return out.view(bool) @cython.wraparound(False) diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index 528d30ddd7205..78e1269aa5363 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -816,7 +816,8 @@ def shift_months(int64_t[:] dtindex, int months, object day=None): return np.asarray(out) -cpdef datetime shift_month(datetime stamp, int months, object day_opt=None): +def shift_month(stamp: datetime, months: int, + day_opt: object=None) -> datetime: """ Given a datetime (or Timestamp) `stamp`, an integer `months` and an option `day_opt`, return a new datetimelike that many months later, @@ -946,8 +947,8 @@ cpdef int roll_convention(int other, int n, int compare) nogil: return n -cpdef int roll_qtrday(datetime other, int n, int month, object day_opt, - int modby=3) except? -1: +def roll_qtrday(other: datetime, n: int, month: int, + day_opt: object, modby: int=3) -> int: """ Possibly increment or decrement the number of periods to shift based on rollforward/rollbackward conventions. diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index 74bbc64af25f2..fa965e2ca7c8c 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -6,6 +6,7 @@ import warnings import sys cdef bint PY3 = (sys.version_info[0] >= 3) +import cython from cython import Py_ssize_t from cpython cimport Py_NE, Py_EQ, PyObject_RichCompare @@ -82,6 +83,8 @@ _no_input = object() # ---------------------------------------------------------------------- # API +@cython.boundscheck(False) +@cython.wraparound(False) def ints_to_pytimedelta(int64_t[:] arr, box=False): """ convert an i8 repr to an ndarray of timedelta or Timedelta (if box == @@ -198,6 +201,8 @@ cpdef convert_to_timedelta64(object ts, object unit): return ts.astype('timedelta64[ns]') +@cython.boundscheck(False) +@cython.wraparound(False) def array_to_timedelta64(object[:] values, unit='ns', errors='raise'): """ Convert an ndarray to an array of timedeltas. If errors == 'coerce', diff --git a/pandas/_libs/window.pyx b/pandas/_libs/window.pyx index c7cfaab60b606..c4af4a6b35a37 100644 --- a/pandas/_libs/window.pyx +++ b/pandas/_libs/window.pyx @@ -1449,8 +1449,8 @@ def roll_quantile(ndarray[float64_t, cast=True] values, int64_t win, try: interpolation_type = interpolation_types[interpolation] except KeyError: - raise ValueError("Interpolation '{}' is not supported" - .format(interpolation)) + raise ValueError("Interpolation '{interp}' is not supported" + .format(interp=interpolation)) # we use the Fixed/Variable Indexer here as the # actual skiplist ops outweigh any window computation costs