Skip to content

CLN: remove DatetimeLikeArray._add_delta #32799

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

Merged
merged 3 commits into from
Mar 19, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 26 additions & 35 deletions pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -1151,56 +1151,46 @@ def _sub_period(self, other):
def _add_offset(self, offset):
raise AbstractMethodError(self)

def _add_delta(self, other):
def _add_timedeltalike_scalar(self, other):
"""
Add a timedelta-like, Tick or TimedeltaIndex-like object
to self, yielding an int64 numpy array

Parameters
----------
delta : {timedelta, np.timedelta64, Tick,
TimedeltaIndex, ndarray[timedelta64]}
Add a delta of a timedeltalike

Returns
-------
result : ndarray[int64]

Notes
-----
The result's name is set outside of _add_delta by the calling
method (__add__ or __sub__), if necessary (i.e. for Indexes).
"""
if isinstance(other, (Tick, timedelta, np.timedelta64)):
new_values = self._add_timedeltalike_scalar(other)
elif is_timedelta64_dtype(other):
# ndarray[timedelta64] or TimedeltaArray/index
new_values = self._add_delta_tdi(other)

return new_values

def _add_timedeltalike_scalar(self, other):
"""
Add a delta of a timedeltalike
return the i8 result view
Same type as self
"""
if isna(other):
# i.e np.timedelta64("NaT"), not recognized by delta_to_nanoseconds
new_values = np.empty(self.shape, dtype="i8")
new_values[:] = iNaT
return new_values
return type(self)(new_values, dtype=self.dtype)

inc = delta_to_nanoseconds(other)
new_values = checked_add_with_arr(self.asi8, inc, arr_mask=self._isnan).view(
"i8"
)
new_values = self._maybe_mask_results(new_values)
return new_values.view("i8")

new_freq = None
if isinstance(self.freq, Tick) or is_period_dtype(self.dtype):
# adding a scalar preserves freq
new_freq = self.freq

if new_freq is not None:
# fastpath that doesnt require inference
return type(self)(new_values, dtype=self.dtype, freq=new_freq)
return type(self)._from_sequence(new_values, dtype=self.dtype, freq="infer")

def _add_delta_tdi(self, other):
"""
Add a delta of a TimedeltaIndex
return the i8 result view

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, this name now looks confusing (because of the word delta), maybe

_add_timedeltaindex

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed to add_timedelta_arraylike

Returns
-------
Same type as self
"""
# overriden by PeriodArray

if len(self) != len(other):
raise ValueError("cannot add indices of unequal length")

Expand All @@ -1218,7 +1208,8 @@ def _add_delta_tdi(self, other):
if self._hasnans or other._hasnans:
mask = (self._isnan) | (other._isnan)
new_values[mask] = iNaT
return new_values.view("i8")

return type(self)._from_sequence(new_values, dtype=self.dtype, freq="infer")

def _add_nat(self):
"""
Expand Down Expand Up @@ -1360,7 +1351,7 @@ def __add__(self, other):
if other is NaT:
result = self._add_nat()
elif isinstance(other, (Tick, timedelta, np.timedelta64)):
result = self._add_delta(other)
result = self._add_timedeltalike_scalar(other)
elif isinstance(other, DateOffset):
# specifically _not_ a Tick
result = self._add_offset(other)
Expand All @@ -1376,7 +1367,7 @@ def __add__(self, other):
# array-like others
elif is_timedelta64_dtype(other):
# TimedeltaIndex, ndarray[timedelta64]
result = self._add_delta(other)
result = self._add_delta_tdi(other)
elif is_object_dtype(other):
# e.g. Array/Index of DateOffset objects
result = self._addsub_object_array(other, operator.add)
Expand Down Expand Up @@ -1412,7 +1403,7 @@ def __sub__(self, other):
if other is NaT:
result = self._sub_nat()
elif isinstance(other, (Tick, timedelta, np.timedelta64)):
result = self._add_delta(-other)
result = self._add_timedeltalike_scalar(-other)
elif isinstance(other, DateOffset):
# specifically _not_ a Tick
result = self._add_offset(-other)
Expand All @@ -1431,7 +1422,7 @@ def __sub__(self, other):
# array-like others
elif is_timedelta64_dtype(other):
# TimedeltaIndex, ndarray[timedelta64]
result = self._add_delta(-other)
result = self._add_delta_tdi(-other)
elif is_object_dtype(other):
# e.g. Array/Index of DateOffset objects
result = self._addsub_object_array(other, operator.sub)
Expand Down
17 changes: 0 additions & 17 deletions pandas/core/arrays/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -718,23 +718,6 @@ def _sub_datetimelike_scalar(self, other):
result = self._maybe_mask_results(result)
return result.view("timedelta64[ns]")

def _add_delta(self, delta):
"""
Add a timedelta-like, Tick, or TimedeltaIndex-like object
to self, yielding a new DatetimeArray

Parameters
----------
other : {timedelta, np.timedelta64, Tick,
TimedeltaIndex, ndarray[timedelta64]}

Returns
-------
result : DatetimeArray
"""
new_values = super()._add_delta(delta)
return type(self)._from_sequence(new_values, tz=self.tz, freq="infer")

# -----------------------------------------------------------------
# Timezone Conversion and Localization Methods

Expand Down
38 changes: 10 additions & 28 deletions pandas/core/arrays/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -657,10 +657,11 @@ def _add_timedeltalike_scalar(self, other):

Returns
-------
result : ndarray[int64]
PeriodArray
"""
assert isinstance(self.freq, Tick) # checked by calling function
assert isinstance(other, (timedelta, np.timedelta64, Tick))
if not isinstance(self.freq, Tick):
# We cannot add timedelta-like to non-tick PeriodArray
raise raise_on_incompatible(self, other)

if notna(other):
# special handling for np.timedelta64("NaT"), avoid calling
Expand All @@ -670,8 +671,7 @@ def _add_timedeltalike_scalar(self, other):
# Note: when calling parent class's _add_timedeltalike_scalar,
# it will call delta_to_nanoseconds(delta). Because delta here
# is an integer, delta_to_nanoseconds will return it unchanged.
ordinals = super()._add_timedeltalike_scalar(other)
return ordinals
return super()._add_timedeltalike_scalar(other)

def _add_delta_tdi(self, other):
"""
Expand All @@ -683,36 +683,18 @@ def _add_delta_tdi(self, other):
-------
result : ndarray[int64]
"""
assert isinstance(self.freq, Tick) # checked by calling function
if not isinstance(self.freq, Tick):
# We cannot add timedelta-like to non-tick PeriodArray
raise raise_on_incompatible(self, other)

if not np.all(isna(other)):
delta = self._check_timedeltalike_freq_compat(other)
else:
# all-NaT TimedeltaIndex is equivalent to a single scalar td64 NaT
return self + np.timedelta64("NaT")

return self._addsub_int_array(delta, operator.add).asi8

def _add_delta(self, other):
"""
Add a timedelta-like, Tick, or TimedeltaIndex-like object
to self, yielding a new PeriodArray

Parameters
----------
other : {timedelta, np.timedelta64, Tick,
TimedeltaIndex, ndarray[timedelta64]}

Returns
-------
result : PeriodArray
"""
if not isinstance(self.freq, Tick):
# We cannot add timedelta-like to non-tick PeriodArray
raise raise_on_incompatible(self, other)

new_ordinals = super()._add_delta(other)
return type(self)(new_ordinals, freq=self.freq)
ordinals = self._addsub_int_array(delta, operator.add).asi8
return type(self)(ordinals, dtype=self.dtype)

def _check_timedeltalike_freq_compat(self, other):
"""
Expand Down
17 changes: 0 additions & 17 deletions pandas/core/arrays/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,23 +400,6 @@ def _add_offset(self, other):
f"cannot add the type {type(other).__name__} to a {type(self).__name__}"
)

def _add_delta(self, delta):
"""
Add a timedelta-like, Tick, or TimedeltaIndex-like object
to self, yielding a new TimedeltaArray.

Parameters
----------
other : {timedelta, np.timedelta64, Tick,
TimedeltaIndex, ndarray[timedelta64]}

Returns
-------
result : TimedeltaArray
"""
new_values = super()._add_delta(delta)
return type(self)._from_sequence(new_values, freq="infer")

def _add_datetime_arraylike(self, other):
"""
Add DatetimeArray/Index or ndarray[datetime64] to TimedeltaArray.
Expand Down