24
24
round_nsint64 ,
25
25
)
26
26
from pandas ._typing import DatetimeLikeScalar , DtypeObj
27
- from pandas .compat import set_function_name
28
27
from pandas .compat .numpy import function as nv
29
28
from pandas .errors import AbstractMethodError , NullFrequencyError , PerformanceWarning
30
29
from pandas .util ._decorators import Appender , Substitution , cache_readonly
51
50
52
51
from pandas .core import nanops , ops
53
52
from pandas .core .algorithms import checked_add_with_arr , unique1d , value_counts
53
+ from pandas .core .arraylike import OpsMixin
54
54
from pandas .core .arrays ._mixins import NDArrayBackedExtensionArray
55
- from pandas .core .arrays .base import ExtensionOpsMixin
56
55
import pandas .core .common as com
57
56
from pandas .core .construction import array , extract_array
58
57
from pandas .core .indexers import check_array_indexer , check_setitem_lengths
@@ -73,46 +72,6 @@ class InvalidComparison(Exception):
73
72
pass
74
73
75
74
76
- def _datetimelike_array_cmp (cls , op ):
77
- """
78
- Wrap comparison operations to convert Timestamp/Timedelta/Period-like to
79
- boxed scalars/arrays.
80
- """
81
- opname = f"__{ op .__name__ } __"
82
- nat_result = opname == "__ne__"
83
-
84
- @unpack_zerodim_and_defer (opname )
85
- def wrapper (self , other ):
86
- if self .ndim > 1 and getattr (other , "shape" , None ) == self .shape :
87
- # TODO: handle 2D-like listlikes
88
- return op (self .ravel (), other .ravel ()).reshape (self .shape )
89
-
90
- try :
91
- other = self ._validate_comparison_value (other , opname )
92
- except InvalidComparison :
93
- return invalid_comparison (self , other , op )
94
-
95
- dtype = getattr (other , "dtype" , None )
96
- if is_object_dtype (dtype ):
97
- # We have to use comp_method_OBJECT_ARRAY instead of numpy
98
- # comparison otherwise it would fail to raise when
99
- # comparing tz-aware and tz-naive
100
- with np .errstate (all = "ignore" ):
101
- result = ops .comp_method_OBJECT_ARRAY (op , self .astype (object ), other )
102
- return result
103
-
104
- other_i8 = self ._unbox (other )
105
- result = op (self .asi8 , other_i8 )
106
-
107
- o_mask = isna (other )
108
- if self ._hasnans | np .any (o_mask ):
109
- result [self ._isnan | o_mask ] = nat_result
110
-
111
- return result
112
-
113
- return set_function_name (wrapper , opname , cls )
114
-
115
-
116
75
class AttributesMixin :
117
76
_data : np .ndarray
118
77
@@ -426,9 +385,7 @@ def _with_freq(self, freq):
426
385
DatetimeLikeArrayT = TypeVar ("DatetimeLikeArrayT" , bound = "DatetimeLikeArrayMixin" )
427
386
428
387
429
- class DatetimeLikeArrayMixin (
430
- ExtensionOpsMixin , AttributesMixin , NDArrayBackedExtensionArray
431
- ):
388
+ class DatetimeLikeArrayMixin (OpsMixin , AttributesMixin , NDArrayBackedExtensionArray ):
432
389
"""
433
390
Shared Base/Mixin class for DatetimeArray, TimedeltaArray, PeriodArray
434
391
@@ -1093,7 +1050,35 @@ def _is_unique(self):
1093
1050
1094
1051
# ------------------------------------------------------------------
1095
1052
# Arithmetic Methods
1096
- _create_comparison_method = classmethod (_datetimelike_array_cmp )
1053
+
1054
+ def _cmp_method (self , other , op ):
1055
+ if self .ndim > 1 and getattr (other , "shape" , None ) == self .shape :
1056
+ # TODO: handle 2D-like listlikes
1057
+ return op (self .ravel (), other .ravel ()).reshape (self .shape )
1058
+
1059
+ try :
1060
+ other = self ._validate_comparison_value (other , f"__{ op .__name__ } __" )
1061
+ except InvalidComparison :
1062
+ return invalid_comparison (self , other , op )
1063
+
1064
+ dtype = getattr (other , "dtype" , None )
1065
+ if is_object_dtype (dtype ):
1066
+ # We have to use comp_method_OBJECT_ARRAY instead of numpy
1067
+ # comparison otherwise it would fail to raise when
1068
+ # comparing tz-aware and tz-naive
1069
+ with np .errstate (all = "ignore" ):
1070
+ result = ops .comp_method_OBJECT_ARRAY (op , self .astype (object ), other )
1071
+ return result
1072
+
1073
+ other_i8 = self ._unbox (other )
1074
+ result = op (self .asi8 , other_i8 )
1075
+
1076
+ o_mask = isna (other )
1077
+ if self ._hasnans | np .any (o_mask ):
1078
+ nat_result = op is operator .ne
1079
+ result [self ._isnan | o_mask ] = nat_result
1080
+
1081
+ return result
1097
1082
1098
1083
# pow is invalid for all three subclasses; TimedeltaArray will override
1099
1084
# the multiplication and division ops
@@ -1582,8 +1567,6 @@ def median(self, axis: Optional[int] = None, skipna: bool = True, *args, **kwarg
1582
1567
return self ._from_backing_data (result .astype ("i8" ))
1583
1568
1584
1569
1585
- DatetimeLikeArrayMixin ._add_comparison_ops ()
1586
-
1587
1570
# -------------------------------------------------------------------
1588
1571
# Shared Constructor Helpers
1589
1572
0 commit comments