Skip to content

Commit

Permalink
REF/TST: Fix remaining DatetimeArray with DateOffset arithmetic ops (p…
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrockmendel authored and Pingviinituutti committed Feb 28, 2019
1 parent 5d9f663 commit cfa19c2
Show file tree
Hide file tree
Showing 9 changed files with 323 additions and 250 deletions.
6 changes: 4 additions & 2 deletions pandas/_libs/tslibs/timestamps.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -377,13 +377,15 @@ cdef class _Timestamp(datetime):
neg_other = -other
return self + neg_other

typ = getattr(other, '_typ', None)

# a Timestamp-DatetimeIndex -> yields a negative TimedeltaIndex
elif getattr(other, '_typ', None) == 'datetimeindex':
if typ in ('datetimeindex', 'datetimearray'):
# timezone comparison is performed in DatetimeIndex._sub_datelike
return -other.__sub__(self)

# a Timestamp-TimedeltaIndex -> yields a negative TimedeltaIndex
elif getattr(other, '_typ', None) == 'timedeltaindex':
elif typ in ('timedeltaindex', 'timedeltaarray'):
return (-other).__add__(self)

elif other is NaT:
Expand Down
43 changes: 36 additions & 7 deletions pandas/core/arrays/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import numpy as np

from pandas._libs import tslibs
from pandas._libs import algos, tslibs
from pandas._libs.tslibs import NaT, Timedelta, Timestamp, iNaT
from pandas._libs.tslibs.fields import get_timedelta_field
from pandas._libs.tslibs.timedeltas import (
Expand All @@ -24,7 +24,7 @@
from pandas.core.dtypes.missing import isna

from pandas.core import ops
from pandas.core.algorithms import checked_add_with_arr
from pandas.core.algorithms import checked_add_with_arr, unique1d
import pandas.core.common as com

from pandas.tseries.frequencies import to_offset
Expand Down Expand Up @@ -162,15 +162,29 @@ def _simple_new(cls, values, freq=None, dtype=_TD_DTYPE):
result._freq = freq
return result

def __new__(cls, values, freq=None, dtype=_TD_DTYPE):
def __new__(cls, values, freq=None, dtype=_TD_DTYPE, copy=False):

freq, freq_infer = dtl.maybe_infer_freq(freq)

values = np.array(values, copy=False)
if values.dtype == np.object_:
values = array_to_timedelta64(values)
values, inferred_freq = sequence_to_td64ns(
values, copy=copy, unit=None)
if inferred_freq is not None:
if freq is not None and freq != inferred_freq:
raise ValueError('Inferred frequency {inferred} from passed '
'values does not conform to passed frequency '
'{passed}'
.format(inferred=inferred_freq,
passed=freq.freqstr))
elif freq is None:
freq = inferred_freq
freq_infer = False

result = cls._simple_new(values, freq=freq)
# check that we are matching freqs
if inferred_freq is None and len(result) > 0:
if freq is not None and not freq_infer:
cls._validate_frequency(result, freq)

if freq_infer:
result.freq = to_offset(result.inferred_freq)

Expand Down Expand Up @@ -227,6 +241,21 @@ def _validate_fill_value(self, fill_value):
"Got '{got}'.".format(got=fill_value))
return fill_value

# monotonicity/uniqueness properties are called via frequencies.infer_freq,
# see GH#23789

@property
def _is_monotonic_increasing(self):
return algos.is_monotonic(self.asi8, timelike=True)[0]

@property
def _is_monotonic_decreasing(self):
return algos.is_monotonic(self.asi8, timelike=True)[1]

@property
def _is_unique(self):
return len(unique1d(self.asi8)) == len(self)

# ----------------------------------------------------------------
# Arithmetic Methods

Expand Down Expand Up @@ -283,7 +312,7 @@ def _add_datetimelike_scalar(self, other):
result = checked_add_with_arr(i8, other.value,
arr_mask=self._isnan)
result = self._maybe_mask_results(result)
return DatetimeArrayMixin(result, tz=other.tz)
return DatetimeArrayMixin(result, tz=other.tz, freq=self.freq)

def _addsub_offset_array(self, other, op):
# Add or subtract Array-like of DateOffset objects
Expand Down
5 changes: 5 additions & 0 deletions pandas/core/indexes/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,11 @@ def slice_indexer(self, start=None, end=None, step=None, kind=None):
# --------------------------------------------------------------------
# Wrapping DatetimeArray

# Compat for frequency inference, see GH#23789
_is_monotonic_increasing = Index.is_monotonic_increasing
_is_monotonic_decreasing = Index.is_monotonic_decreasing
_is_unique = Index.is_unique

_timezone = cache_readonly(DatetimeArray._timezone.fget)
is_normalized = cache_readonly(DatetimeArray.is_normalized.fget)
_resolution = cache_readonly(DatetimeArray._resolution.fget)
Expand Down
5 changes: 5 additions & 0 deletions pandas/core/indexes/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,11 @@ def _format_native_types(self, na_rep=u'NaT', date_format=None, **kwargs):

total_seconds = wrap_array_method(TimedeltaArray.total_seconds, True)

# Compat for frequency inference, see GH#23789
_is_monotonic_increasing = Index.is_monotonic_increasing
_is_monotonic_decreasing = Index.is_monotonic_decreasing
_is_unique = Index.is_unique

# -------------------------------------------------------------------

@Appender(_index_shared_docs['astype'])
Expand Down
Loading

0 comments on commit cfa19c2

Please sign in to comment.