-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
De-duplicate add_offset_array methods #19835
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
f8dce25
3b3882b
1bc093c
280b178
37c7c57
34a49a3
db45591
382ca8b
b2e405f
678908e
3abc51f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
Base and utility classes for tseries type pandas objects. | ||
""" | ||
import warnings | ||
|
||
import operator | ||
from datetime import datetime, timedelta | ||
|
||
from pandas import compat | ||
|
@@ -25,13 +25,14 @@ | |
is_integer_dtype, | ||
is_object_dtype, | ||
is_string_dtype, | ||
is_period_dtype, | ||
is_timedelta64_dtype) | ||
from pandas.core.dtypes.generic import ( | ||
ABCIndex, ABCSeries, ABCPeriodIndex, ABCIndexClass) | ||
from pandas.core.dtypes.missing import isna | ||
from pandas.core import common as com, algorithms, ops | ||
from pandas.core.algorithms import checked_add_with_arr | ||
from pandas.errors import NullFrequencyError | ||
from pandas.errors import NullFrequencyError, PerformanceWarning | ||
import pandas.io.formats.printing as printing | ||
from pandas._libs import lib, iNaT, NaT | ||
from pandas._libs.tslibs.period import Period | ||
|
@@ -637,13 +638,32 @@ def _sub_datelike(self, other): | |
def _sub_period(self, other): | ||
return NotImplemented | ||
|
||
def _add_offset_array(self, other): | ||
# Array/Index of DateOffset objects | ||
return NotImplemented | ||
def _addsub_offset_array(self, other, op): | ||
""" | ||
Add or subtract array-like of DateOffset objects | ||
|
||
def _sub_offset_array(self, other): | ||
# Array/Index of DateOffset objects | ||
return NotImplemented | ||
Parameters | ||
---------- | ||
other : Index, np.ndarray | ||
object-dtype containing pd.DateOffset objects | ||
op : {operator.add, operator.sub} | ||
|
||
Returns | ||
------- | ||
result : same class as self | ||
""" | ||
if len(other) == 1: | ||
return op(self, other[0]) | ||
|
||
warnings.warn("Adding/subtracting array of DateOffsets to " | ||
"{cls} not vectorized" | ||
.format(cls=type(self).__name__), PerformanceWarning) | ||
|
||
res_values = op(self.astype('O').values, np.array(other)) | ||
kwargs = {} | ||
if not is_period_dtype(self): | ||
kwargs['freq'] = 'infer' | ||
return self.__class__(res_values, **kwargs) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed it to shallow_copy and it broke several tests, so just pushed with it changed back to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so try using |
||
|
||
@classmethod | ||
def _add_datetimelike_methods(cls): | ||
|
@@ -660,25 +680,30 @@ def __add__(self, other): | |
other = lib.item_from_zerodim(other) | ||
if isinstance(other, ABCSeries): | ||
return NotImplemented | ||
elif is_timedelta64_dtype(other): | ||
|
||
# scalar others | ||
elif isinstance(other, (DateOffset, timedelta, np.timedelta64)): | ||
result = self._add_delta(other) | ||
elif isinstance(other, (DateOffset, timedelta)): | ||
elif isinstance(other, (datetime, np.datetime64)): | ||
result = self._add_datelike(other) | ||
elif is_integer(other): | ||
# This check must come after the check for np.timedelta64 | ||
# as is_integer returns True for these | ||
result = self.shift(other) | ||
|
||
# array-like others | ||
elif is_timedelta64_dtype(other): | ||
# TimedeltaIndex, ndarray[timedelta64] | ||
result = self._add_delta(other) | ||
elif is_offsetlike(other): | ||
# Array/Index of DateOffset objects | ||
result = self._add_offset_array(other) | ||
result = self._addsub_offset_array(other, operator.add) | ||
elif isinstance(self, TimedeltaIndex) and isinstance(other, Index): | ||
if hasattr(other, '_add_delta'): | ||
result = other._add_delta(self) | ||
else: | ||
raise TypeError("cannot add TimedeltaIndex and {typ}" | ||
.format(typ=type(other))) | ||
elif is_integer(other): | ||
# This check must come after the check for timedelta64_dtype | ||
# or else it will incorrectly catch np.timedelta64 objects | ||
result = self.shift(other) | ||
elif isinstance(other, (datetime, np.datetime64)): | ||
result = self._add_datelike(other) | ||
elif isinstance(other, Index): | ||
result = self._add_datelike(other) | ||
elif is_integer_dtype(other) and self.freq is None: | ||
|
@@ -704,28 +729,33 @@ def __sub__(self, other): | |
other = lib.item_from_zerodim(other) | ||
if isinstance(other, ABCSeries): | ||
return NotImplemented | ||
elif is_timedelta64_dtype(other): | ||
|
||
# scalar others | ||
elif isinstance(other, (DateOffset, timedelta, np.timedelta64)): | ||
result = self._add_delta(-other) | ||
elif isinstance(other, (DateOffset, timedelta)): | ||
elif isinstance(other, (datetime, np.datetime64)): | ||
result = self._sub_datelike(other) | ||
elif is_integer(other): | ||
# This check must come after the check for np.timedelta64 | ||
# as is_integer returns True for these | ||
result = self.shift(-other) | ||
elif isinstance(other, Period): | ||
result = self._sub_period(other) | ||
|
||
# array-like others | ||
elif is_timedelta64_dtype(other): | ||
# TimedeltaIndex, ndarray[timedelta64] | ||
result = self._add_delta(-other) | ||
elif is_offsetlike(other): | ||
# Array/Index of DateOffset objects | ||
result = self._sub_offset_array(other) | ||
result = self._addsub_offset_array(other, operator.sub) | ||
elif isinstance(self, TimedeltaIndex) and isinstance(other, Index): | ||
if not isinstance(other, TimedeltaIndex): | ||
raise TypeError("cannot subtract TimedeltaIndex and {typ}" | ||
.format(typ=type(other).__name__)) | ||
result = self._add_delta(-other) | ||
elif isinstance(other, DatetimeIndex): | ||
result = self._sub_datelike(other) | ||
elif is_integer(other): | ||
# This check must come after the check for timedelta64_dtype | ||
# or else it will incorrectly catch np.timedelta64 objects | ||
result = self.shift(-other) | ||
elif isinstance(other, (datetime, np.datetime64)): | ||
result = self._sub_datelike(other) | ||
elif isinstance(other, Period): | ||
result = self._sub_period(other) | ||
elif isinstance(other, Index): | ||
raise TypeError("cannot subtract {typ1} and {typ2}" | ||
.format(typ1=type(self).__name__, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you assert on the operator