From 70e976562e0de1f1570db66ae29895df716ebfa8 Mon Sep 17 00:00:00 2001 From: onesandzeroes Date: Thu, 31 Mar 2016 19:29:25 +1100 Subject: [PATCH 1/6] Add test case for loffset when using count() method --- pandas/tseries/tests/test_resample.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pandas/tseries/tests/test_resample.py b/pandas/tseries/tests/test_resample.py index e2de3c5e01ba2..ad2001f7afb54 100644 --- a/pandas/tseries/tests/test_resample.py +++ b/pandas/tseries/tests/test_resample.py @@ -937,6 +937,25 @@ def test_resample_loffset(self): expected = ser.resample('w-sun', loffset=-bday).last() self.assertEqual(result.index[0] - bday, expected.index[0]) + def test_resample_loffset_count(self): + # GH issue 12725 + start_time = '1/1/2000 00:00:00' + rng = date_range(start_time, periods=100, freq='S') + ts = Series(np.random.randn(len(rng)), index=rng) + + result = ts.resample('10S', loffset='1s').count() + + expected_index = date_range(start_time, periods=10, freq='10S') + timedelta(seconds=1) + expected = pd.Series(10, index=expected_index) + + assert_series_equal(result, expected) + + # Same issue should apply to .size() since it goes through + # same code path + result = ts.resample('10S', loffset='1s').size() + + assert_series_equal(result, expected) + def test_resample_upsample(self): # from daily dti = DatetimeIndex(start=datetime(2005, 1, 1), From 15aadb9a9e3ead9f5e46ce37a596e6d8e6ad5e9a Mon Sep 17 00:00:00 2001 From: onesandzeroes Date: Thu, 31 Mar 2016 19:34:23 +1100 Subject: [PATCH 2/6] Extract loffset handling into a general method --- pandas/tseries/resample.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/pandas/tseries/resample.py b/pandas/tseries/resample.py index 0ac10eb4fa15b..ff6e9b99ebb94 100644 --- a/pandas/tseries/resample.py +++ b/pandas/tseries/resample.py @@ -374,6 +374,19 @@ def _groupby_and_aggregate(self, grouper, how, *args, **kwargs): return self._wrap_result(result) + def _apply_loffset(self, result): + """if loffset if set, offset the result index""" + loffset = self.loffset + if isinstance(loffset, compat.string_types): + loffset = to_offset(self.loffset) + + if isinstance(loffset, (DateOffset, timedelta)) and \ + isinstance(result.index, DatetimeIndex) and \ + len(result.index) > 0: + result.index = result.index + loffset + + return result + def _wrap_result(self, result): """ potentially wrap any results """ return result @@ -572,14 +585,7 @@ def _downsample(self, how, **kwargs): result = obj.groupby( self.grouper, axis=self.axis).aggregate(how, **kwargs) - loffset = self.loffset - if isinstance(loffset, compat.string_types): - loffset = to_offset(self.loffset) - - if isinstance(loffset, (DateOffset, timedelta)) and \ - isinstance(result.index, DatetimeIndex) and \ - len(result.index) > 0: - result.index = result.index + loffset + result = self._apply_loffset(result) return self._wrap_result(result) From dc79369c7af2c90ea94f853ddbb123bfe4265572 Mon Sep 17 00:00:00 2001 From: onesandzeroes Date: Thu, 31 Mar 2016 19:35:54 +1100 Subject: [PATCH 3/6] Apply loffset when aggregating, e.g. using count() --- pandas/tseries/resample.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pandas/tseries/resample.py b/pandas/tseries/resample.py index ff6e9b99ebb94..137f7383ba776 100644 --- a/pandas/tseries/resample.py +++ b/pandas/tseries/resample.py @@ -372,6 +372,8 @@ def _groupby_and_aggregate(self, grouper, how, *args, **kwargs): # try to evaluate result = grouped.apply(how, *args, **kwargs) + result = self._apply_loffset(result) + return self._wrap_result(result) def _apply_loffset(self, result): From 0c0ca34a9658ef7ff233ba6e96412d39f6977561 Mon Sep 17 00:00:00 2001 From: onesandzeroes Date: Thu, 31 Mar 2016 21:47:46 +1100 Subject: [PATCH 4/6] Update comment re: issue number --- pandas/tseries/tests/test_resample.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tseries/tests/test_resample.py b/pandas/tseries/tests/test_resample.py index ad2001f7afb54..c2c330df4d3af 100644 --- a/pandas/tseries/tests/test_resample.py +++ b/pandas/tseries/tests/test_resample.py @@ -938,7 +938,7 @@ def test_resample_loffset(self): self.assertEqual(result.index[0] - bday, expected.index[0]) def test_resample_loffset_count(self): - # GH issue 12725 + # GH 12725 start_time = '1/1/2000 00:00:00' rng = date_range(start_time, periods=100, freq='S') ts = Series(np.random.randn(len(rng)), index=rng) From fa021bf8bb8ced23c93107b578ceffc39cf3c12a Mon Sep 17 00:00:00 2001 From: onesandzeroes Date: Thu, 31 Mar 2016 21:52:13 +1100 Subject: [PATCH 5/6] pep8 style fixes --- pandas/tseries/resample.py | 9 ++++++--- pandas/tseries/tests/test_resample.py | 5 ++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pandas/tseries/resample.py b/pandas/tseries/resample.py index 137f7383ba776..8d922dd548e50 100644 --- a/pandas/tseries/resample.py +++ b/pandas/tseries/resample.py @@ -382,9 +382,12 @@ def _apply_loffset(self, result): if isinstance(loffset, compat.string_types): loffset = to_offset(self.loffset) - if isinstance(loffset, (DateOffset, timedelta)) and \ - isinstance(result.index, DatetimeIndex) and \ - len(result.index) > 0: + needs_offset = ( + isinstance(loffset, (DateOffset, timedelta)) and + isinstance(result.index, DatetimeIndex) and + len(result.index) > 0 + ) + if needs_offset: result.index = result.index + loffset return result diff --git a/pandas/tseries/tests/test_resample.py b/pandas/tseries/tests/test_resample.py index c2c330df4d3af..f4e2f056c0781 100644 --- a/pandas/tseries/tests/test_resample.py +++ b/pandas/tseries/tests/test_resample.py @@ -945,7 +945,10 @@ def test_resample_loffset_count(self): result = ts.resample('10S', loffset='1s').count() - expected_index = date_range(start_time, periods=10, freq='10S') + timedelta(seconds=1) + expected_index = ( + date_range(start_time, periods=10, freq='10S') + + timedelta(seconds=1) + ) expected = pd.Series(10, index=expected_index) assert_series_equal(result, expected) From 627429a2e546cae26576acfdd00855dca968de85 Mon Sep 17 00:00:00 2001 From: onesandzeroes Date: Fri, 1 Apr 2016 00:01:10 +1100 Subject: [PATCH 6/6] Add to release notes --- doc/source/whatsnew/v0.18.1.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v0.18.1.txt b/doc/source/whatsnew/v0.18.1.txt index 1179a347e4c46..6f3a5cc45c918 100644 --- a/doc/source/whatsnew/v0.18.1.txt +++ b/doc/source/whatsnew/v0.18.1.txt @@ -169,3 +169,4 @@ Bug Fixes - Bug in ``pivot_table`` when ``margins=True`` and ``dropna=True`` where nulls still contributed to margin count (:issue:`12577`) - Bug in ``Series.name`` when ``name`` attribute can be a hashable type (:issue:`12610`) - Bug in ``.describe()`` resets categorical columns information (:issue:`11558`) +- Bug where ``loffset`` argument was not applied when calling ``resample().count()`` on a timeseries (:issue:`12725`)