Skip to content

Commit 23e5cfc

Browse files
committed
Use ._tshift internally for datetimelike ops
In preperation for PeriodArray / DatetimeArray / TimedeltaArray. Index.shift has a different meaning from ExtensionArray.shift. - Index.shift pointwise shifts each element by some amount - ExtensionArray.shift shits the *position* of each value in the array padding the end with NA This is going to get confusing. This PR tries to avoid some of that by internally using a new `_tshift` method (time-shift) when we want to do pointwise shifting of each value. Places that know they want that behavior (like in the datetimelike ops) should use that.
1 parent 1d9f76c commit 23e5cfc

File tree

2 files changed

+26
-6
lines changed

2 files changed

+26
-6
lines changed

pandas/core/arrays/datetimelike.py

+20-3
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ def _sub_period_array(self, other):
455455
def _addsub_int_array(self, other, op):
456456
"""
457457
Add or subtract array-like of integers equivalent to applying
458-
`shift` pointwise.
458+
`_tshift` pointwise.
459459
460460
Parameters
461461
----------
@@ -553,6 +553,23 @@ def shift(self, periods, freq=None):
553553
--------
554554
Index.shift : Shift values of Index.
555555
"""
556+
return self._tshift(periods=periods, freq=freq)
557+
558+
def _tshift(self, periods, freq=None):
559+
"""
560+
Shift each value by `periods`.
561+
562+
Note this is different from ExtensionArray.shift, which
563+
shifts the *position* of each element, padding the end with
564+
missing values.
565+
566+
Parameters
567+
----------
568+
periods : int
569+
Number of periods to shift by.
570+
freq : pandas.DateOffset, pandas.Timedelta, or string
571+
Frequency increment to shift by.
572+
"""
556573
if freq is not None and freq != self.freq:
557574
if isinstance(freq, compat.string_types):
558575
freq = frequencies.to_offset(freq)
@@ -600,7 +617,7 @@ def __add__(self, other):
600617
elif lib.is_integer(other):
601618
# This check must come after the check for np.timedelta64
602619
# as is_integer returns True for these
603-
result = self.shift(other)
620+
result = self._tshift(other)
604621

605622
# array-like others
606623
elif is_timedelta64_dtype(other):
@@ -652,7 +669,7 @@ def __sub__(self, other):
652669
elif lib.is_integer(other):
653670
# This check must come after the check for np.timedelta64
654671
# as is_integer returns True for these
655-
result = self.shift(-other)
672+
result = self._tshift(-other)
656673
elif isinstance(other, Period):
657674
result = self._sub_period(other)
658675

pandas/core/arrays/period.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ def _add_offset(self, other):
297297
if base != self.freq.rule_code:
298298
msg = DIFFERENT_FREQ_INDEX.format(self.freqstr, other.freqstr)
299299
raise IncompatibleFrequency(msg)
300-
return self.shift(other.n)
300+
return self._tshift(other.n)
301301

302302
def _add_delta_td(self, other):
303303
assert isinstance(other, (timedelta, np.timedelta64, Tick))
@@ -307,7 +307,7 @@ def _add_delta_td(self, other):
307307
if isinstance(own_offset, Tick):
308308
offset_nanos = delta_to_nanoseconds(own_offset)
309309
if np.all(nanos % offset_nanos == 0):
310-
return self.shift(nanos // offset_nanos)
310+
return self._tshift(nanos // offset_nanos)
311311

312312
# raise when input doesn't have freq
313313
raise IncompatibleFrequency("Input has different freq from "
@@ -317,7 +317,7 @@ def _add_delta_td(self, other):
317317

318318
def _add_delta(self, other):
319319
ordinal_delta = self._maybe_convert_timedelta(other)
320-
return self.shift(ordinal_delta)
320+
return self._tshift(ordinal_delta)
321321

322322
def shift(self, n):
323323
"""
@@ -332,6 +332,9 @@ def shift(self, n):
332332
-------
333333
shifted : Period Array/Index
334334
"""
335+
return self._tshift(n)
336+
337+
def _tshift(self, n):
335338
values = self._ndarray_values + n * self.freq.n
336339
if self.hasnans:
337340
values[self._isnan] = iNaT

0 commit comments

Comments
 (0)