From c404c4373049a4e457fa4051e2b386a9f146df65 Mon Sep 17 00:00:00 2001 From: jreback Date: Wed, 18 Jun 2014 17:37:09 -0400 Subject: [PATCH] BUG: Bug in timeops with non-aligned Series (GH7500) --- doc/source/v0.14.1.txt | 4 ++-- pandas/core/ops.py | 12 ++++++++++-- pandas/tests/test_series.py | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/doc/source/v0.14.1.txt b/doc/source/v0.14.1.txt index c1e5877d09004..930ba13bef122 100644 --- a/doc/source/v0.14.1.txt +++ b/doc/source/v0.14.1.txt @@ -165,10 +165,10 @@ Bug Fixes ~~~~~~~~~ +- Bug in timeops with non-aligned Series (:issue:`7500`) - -- Bug in ``value_counts`` where ``NaT`` did not qualify as missing (``NaN``) (:issue:`7423`) +- Bug in ``value_counts`` where ``NaT`` did not qualify as missing (``NaN``) (:issue:`7423`) diff --git a/pandas/core/ops.py b/pandas/core/ops.py index 0f19634cb5a38..780edec6ea25b 100644 --- a/pandas/core/ops.py +++ b/pandas/core/ops.py @@ -245,6 +245,12 @@ class _TimeOp(object): def __init__(self, left, right, name): self.name = name + # need to make sure that we are aligning the data + if isinstance(left, pd.Series) and isinstance(right, pd.Series): + left, right = left.align(right) + + self.left = left + self.right = right lvalues = self._convert_to_array(left, name=name) rvalues = self._convert_to_array(right, name=name, other=lvalues) @@ -426,6 +432,7 @@ def maybe_convert_for_time_op(cls, left, right, name): is_datetime_lhs = com.is_datetime64_dtype(left) if not (is_datetime_lhs or is_timedelta_lhs): return None + # rops are allowed. No need for special checks, just strip off # r part. if name.startswith('__r'): @@ -463,6 +470,7 @@ def wrapper(left, right, name=name): if isinstance(right, pd.DataFrame): return NotImplemented + time_converted = _TimeOp.maybe_convert_for_time_op(left, right, name) if time_converted is None: @@ -472,8 +480,8 @@ def wrapper(left, right, name=name): elif time_converted == NotImplemented: return NotImplemented else: - lvalues = time_converted.lvalues - rvalues = time_converted.rvalues + left, right = time_converted.left, time_converted.right + lvalues, rvalues = time_converted.lvalues, time_converted.rvalues dtype = time_converted.dtype wrap_results = time_converted.wrap_results diff --git a/pandas/tests/test_series.py b/pandas/tests/test_series.py index 2e3a9d922bb47..eb2b53dff3879 100644 --- a/pandas/tests/test_series.py +++ b/pandas/tests/test_series.py @@ -2838,6 +2838,24 @@ def run_ops(ops, get_ser, test_ser): td1 + dt1 dt1 + td1 + def test_ops_datetimelike_align(self): + if _np_version_under1p7: + raise nose.SkipTest("timedelta broken in np < 1.7") + + # GH 7500 + # datetimelike ops need to align + dt = Series(date_range('2012-1-1', periods=3, freq='D')) + dt.iloc[2] = np.nan + dt2 = dt[::-1] + + expected = Series([timedelta(0),timedelta(0),pd.NaT]) + + result = dt2-dt + assert_series_equal(result,expected) + + result = (dt2.to_frame()-dt.to_frame())[0] + assert_series_equal(result,expected) + def test_timedelta64_functions(self): from datetime import timedelta