Skip to content

Commit 7dc9646

Browse files
jbrockmendelNo-Stream
authored andcommitted
Move comparison utilities to np_datetime; (pandas-dev#18080)
1 parent 4a14a45 commit 7dc9646

File tree

3 files changed

+41
-29
lines changed

3 files changed

+41
-29
lines changed

pandas/_libs/tslib.pyx

+6-29
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ from datetime cimport (
5555
from datetime import time as datetime_time
5656

5757
from tslibs.np_datetime cimport (check_dts_bounds,
58+
reverse_ops,
59+
cmp_scalar,
5860
pandas_datetimestruct,
5961
dt64_to_dtstruct, dtstruct_to_dt64,
6062
pydatetime_to_dt64, pydate_to_dt64)
@@ -893,31 +895,6 @@ def unique_deltas(ndarray[int64_t] arr):
893895
return result
894896

895897

896-
cdef inline bint _cmp_scalar(int64_t lhs, int64_t rhs, int op) except -1:
897-
if op == Py_EQ:
898-
return lhs == rhs
899-
elif op == Py_NE:
900-
return lhs != rhs
901-
elif op == Py_LT:
902-
return lhs < rhs
903-
elif op == Py_LE:
904-
return lhs <= rhs
905-
elif op == Py_GT:
906-
return lhs > rhs
907-
elif op == Py_GE:
908-
return lhs >= rhs
909-
910-
911-
cdef int _reverse_ops[6]
912-
913-
_reverse_ops[Py_LT] = Py_GT
914-
_reverse_ops[Py_LE] = Py_GE
915-
_reverse_ops[Py_EQ] = Py_EQ
916-
_reverse_ops[Py_NE] = Py_NE
917-
_reverse_ops[Py_GT] = Py_LT
918-
_reverse_ops[Py_GE] = Py_LE
919-
920-
921898
cdef str _NDIM_STRING = "ndim"
922899

923900
# This is PITA. Because we inherit from datetime, which has very specific
@@ -970,7 +947,7 @@ cdef class _Timestamp(datetime):
970947
raise TypeError('Cannot compare type %r with type %r' %
971948
(type(self).__name__,
972949
type(other).__name__))
973-
return PyObject_RichCompare(other, self, _reverse_ops[op])
950+
return PyObject_RichCompare(other, self, reverse_ops[op])
974951
else:
975952
if op == Py_EQ:
976953
return False
@@ -980,7 +957,7 @@ cdef class _Timestamp(datetime):
980957
(type(self).__name__, type(other).__name__))
981958

982959
self._assert_tzawareness_compat(other)
983-
return _cmp_scalar(self.value, ots.value, op)
960+
return cmp_scalar(self.value, ots.value, op)
984961

985962
def __reduce_ex__(self, protocol):
986963
# python 3.6 compat
@@ -2066,7 +2043,7 @@ cdef class _Timedelta(timedelta):
20662043
type(other).__name__))
20672044
if util.is_array(other):
20682045
return PyObject_RichCompare(np.array([self]), other, op)
2069-
return PyObject_RichCompare(other, self, _reverse_ops[op])
2046+
return PyObject_RichCompare(other, self, reverse_ops[op])
20702047
else:
20712048
if op == Py_EQ:
20722049
return False
@@ -2075,7 +2052,7 @@ cdef class _Timedelta(timedelta):
20752052
raise TypeError('Cannot compare type %r with type %r' %
20762053
(type(self).__name__, type(other).__name__))
20772054

2078-
return _cmp_scalar(self.value, ots.value, op)
2055+
return cmp_scalar(self.value, ots.value, op)
20792056

20802057
def _ensure_components(_Timedelta self):
20812058
"""

pandas/_libs/tslibs/np_datetime.pxd

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ cdef extern from "../src/datetime/np_datetime.h":
1212
int32_t month, day, hour, min, sec, us, ps, as
1313

1414

15+
cdef int reverse_ops[6]
16+
17+
cdef bint cmp_scalar(int64_t lhs, int64_t rhs, int op) except -1
18+
1519
cdef check_dts_bounds(pandas_datetimestruct *dts)
1620

1721
cdef int64_t dtstruct_to_dt64(pandas_datetimestruct* dts) nogil

pandas/_libs/tslibs/np_datetime.pyx

+31
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# -*- coding: utf-8 -*-
22
# cython: profile=False
33

4+
from cpython cimport Py_EQ, Py_NE, Py_GE, Py_GT, Py_LT, Py_LE
5+
46
from cpython.datetime cimport (datetime, date,
57
PyDateTime_IMPORT,
68
PyDateTime_GET_YEAR, PyDateTime_GET_MONTH,
@@ -47,6 +49,35 @@ cdef extern from "../src/datetime/np_datetime.h":
4749
pandas_datetimestruct _NS_MIN_DTS, _NS_MAX_DTS
4850

4951
# ----------------------------------------------------------------------
52+
# Comparison
53+
54+
cdef int reverse_ops[6]
55+
56+
reverse_ops[Py_LT] = Py_GT
57+
reverse_ops[Py_LE] = Py_GE
58+
reverse_ops[Py_EQ] = Py_EQ
59+
reverse_ops[Py_NE] = Py_NE
60+
reverse_ops[Py_GT] = Py_LT
61+
reverse_ops[Py_GE] = Py_LE
62+
63+
64+
cdef inline bint cmp_scalar(int64_t lhs, int64_t rhs, int op) except -1:
65+
"""
66+
cmp_scalar is a more performant version of PyObject_RichCompare
67+
typed for int64_t arguments.
68+
"""
69+
if op == Py_EQ:
70+
return lhs == rhs
71+
elif op == Py_NE:
72+
return lhs != rhs
73+
elif op == Py_LT:
74+
return lhs < rhs
75+
elif op == Py_LE:
76+
return lhs <= rhs
77+
elif op == Py_GT:
78+
return lhs > rhs
79+
elif op == Py_GE:
80+
return lhs >= rhs
5081

5182

5283
class OutOfBoundsDatetime(ValueError):

0 commit comments

Comments
 (0)