Skip to content

Commit 838e8da

Browse files
jbrockmendeljreback
authored andcommitted
More speedups for Period comparisons (#21606)
1 parent 2a7e1f2 commit 838e8da

File tree

3 files changed

+46
-31
lines changed

3 files changed

+46
-31
lines changed

doc/source/whatsnew/v0.24.0.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ Performance Improvements
135135

136136
- Improved performance of :func:`Series.describe` in case of numeric dtpyes (:issue:`21274`)
137137
- Improved performance of :func:`pandas.core.groupby.GroupBy.rank` when dealing with tied rankings (:issue:`21237`)
138-
- Improved performance of :func:`DataFrame.set_index` with columns consisting of :class:`Period` objects (:issue:`21582`)
138+
- Improved performance of :func:`DataFrame.set_index` with columns consisting of :class:`Period` objects (:issue:`21582`,:issue:`21606`)
139139
-
140140

141141
.. _whatsnew_0240.docs:

pandas/_libs/tslibs/offsets.pyx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,15 @@ for _d in DAYS:
8888
# ---------------------------------------------------------------------
8989
# Misc Helpers
9090

91+
cdef to_offset(object obj):
92+
"""
93+
Wrap pandas.tseries.frequencies.to_offset to keep centralize runtime
94+
imports
95+
"""
96+
from pandas.tseries.frequencies import to_offset
97+
return to_offset(obj)
98+
99+
91100
def as_datetime(obj):
92101
f = getattr(obj, 'to_pydatetime', None)
93102
if f is not None:
@@ -313,6 +322,41 @@ class _BaseOffset(object):
313322
def __setattr__(self, name, value):
314323
raise AttributeError("DateOffset objects are immutable.")
315324

325+
def __eq__(self, other):
326+
if is_string_object(other):
327+
other = to_offset(other)
328+
329+
try:
330+
return self._params == other._params
331+
except AttributeError:
332+
# other is not a DateOffset object
333+
return False
334+
335+
return self._params == other._params
336+
337+
def __ne__(self, other):
338+
return not self == other
339+
340+
def __hash__(self):
341+
return hash(self._params)
342+
343+
@property
344+
def _params(self):
345+
"""
346+
Returns a tuple containing all of the attributes needed to evaluate
347+
equality between two DateOffset objects.
348+
"""
349+
# NB: non-cython subclasses override property with cache_readonly
350+
all_paras = self.__dict__.copy()
351+
if 'holidays' in all_paras and not all_paras['holidays']:
352+
all_paras.pop('holidays')
353+
exclude = ['kwds', 'name', 'calendar']
354+
attrs = [(k, v) for k, v in all_paras.items()
355+
if (k not in exclude) and (k[0] != '_')]
356+
attrs = sorted(set(attrs))
357+
params = tuple([str(self.__class__)] + attrs)
358+
return params
359+
316360
@property
317361
def kwds(self):
318362
# for backwards-compatibility

pandas/tseries/offsets.py

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ def __add__(date):
182182
183183
Since 0 is a bit weird, we suggest avoiding its use.
184184
"""
185+
_params = cache_readonly(BaseOffset._params.fget)
185186
_use_relativedelta = False
186187
_adjust_dst = False
187188
_attributes = frozenset(['n', 'normalize'] +
@@ -288,18 +289,6 @@ def isAnchored(self):
288289
# if there were a canonical docstring for what isAnchored means.
289290
return (self.n == 1)
290291

291-
@cache_readonly
292-
def _params(self):
293-
all_paras = self.__dict__.copy()
294-
if 'holidays' in all_paras and not all_paras['holidays']:
295-
all_paras.pop('holidays')
296-
exclude = ['kwds', 'name', 'calendar']
297-
attrs = [(k, v) for k, v in all_paras.items()
298-
if (k not in exclude) and (k[0] != '_')]
299-
attrs = sorted(set(attrs))
300-
params = tuple([str(self.__class__)] + attrs)
301-
return params
302-
303292
# TODO: Combine this with BusinessMixin version by defining a whitelisted
304293
# set of attributes on each object rather than the existing behavior of
305294
# iterating over internal ``__dict__``
@@ -322,24 +311,6 @@ def _repr_attrs(self):
322311
def name(self):
323312
return self.rule_code
324313

325-
def __eq__(self, other):
326-
327-
if isinstance(other, compat.string_types):
328-
from pandas.tseries.frequencies import to_offset
329-
330-
other = to_offset(other)
331-
332-
if not isinstance(other, DateOffset):
333-
return False
334-
335-
return self._params == other._params
336-
337-
def __ne__(self, other):
338-
return not self == other
339-
340-
def __hash__(self):
341-
return hash(self._params)
342-
343314
def __add__(self, other):
344315
if isinstance(other, (ABCDatetimeIndex, ABCSeries)):
345316
return other + self

0 commit comments

Comments
 (0)