Skip to content

Commit d21725c

Browse files
author
Chang She
committed
ENH loffset in resample. GH #1127
1 parent 6b48af3 commit d21725c

File tree

5 files changed

+33
-24
lines changed

5 files changed

+33
-24
lines changed

pandas/core/generic.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# pylint: disable=W0231
2+
from datetime import timedelta
23

34
import numpy as np
45

56
from pandas.core.common import save, load
67
from pandas.core.index import MultiIndex
78
from pandas.tseries.index import DatetimeIndex
9+
from pandas.tseries.offsets import DateOffset
810

911
#-------------------------------------------------------------------------------
1012
# Picklable mixin
@@ -136,7 +138,8 @@ def groupby(self, by=None, axis=0, level=None, as_index=True, sort=True,
136138
sort=sort, group_keys=group_keys)
137139

138140
def resample(self, rule, how='mean', axis=0, as_index=True,
139-
fill_method=None, closed='right', label='right', kind=None):
141+
fill_method=None, closed='right', label='right', kind=None,
142+
loffset=None):
140143
"""
141144
Convenience method for frequency conversion and resampling of regular
142145
time-series data.
@@ -152,6 +155,8 @@ def resample(self, rule, how='mean', axis=0, as_index=True,
152155
label : {'right', 'left'}, default 'right'
153156
Which bin edge label to label bucket with
154157
as_index : see synonymous argument of groupby
158+
loffset : timedelta
159+
Adjust the resampled time labels
155160
"""
156161
from pandas.tseries.resample import TimeGrouper
157162

@@ -171,6 +176,9 @@ def resample(self, rule, how='mean', axis=0, as_index=True,
171176
# upsampling
172177
result = self.reindex(grouper.binner[1:], method=fill_method)
173178

179+
if isinstance(loffset, (DateOffset, timedelta)):
180+
if len(result.index) > 0:
181+
result.index = result.index + loffset
174182
return result
175183

176184
def first(self, offset):

pandas/core/index.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -436,10 +436,7 @@ def __add__(self, other):
436436
__ge__ = _indexOp('__ge__')
437437

438438
def __sub__(self, other):
439-
if isinstance(other, Index):
440-
return self.diff(other)
441-
else:
442-
return Index(self.view(np.ndarray) - other)
439+
return self.diff(other)
443440

444441
def __and__(self, other):
445442
return self.intersection(other)

pandas/tests/test_index.py

-7
Original file line numberDiff line numberDiff line change
@@ -229,13 +229,6 @@ def test_timedelta(self):
229229
self.assertEqual(shifted.freq, self.dateIndex.freq)
230230
self.assertEqual(shifted.freq, back.freq)
231231

232-
lead = self.dateIndex - timedelta(1)
233-
back = lead - timedelta(-1)
234-
self.assert_(tm.equalContents(self.dateIndex, back))
235-
self.assertEqual(self.dateIndex.freq, back.freq)
236-
self.assertEqual(lead.freq, back.freq)
237-
238-
239232
def test_append_multiple(self):
240233
index = Index(['a', 'b', 'c', 'd', 'e', 'f'])
241234

pandas/tseries/index.py

+1-10
Original file line numberDiff line numberDiff line change
@@ -417,16 +417,7 @@ def __add__(self, other):
417417
return self.union(other)
418418
elif isinstance(other, (datetools.DateOffset, timedelta)):
419419
new_values = self.astype('O') + other
420-
return DatetimeIndex(new_values, tz=self.tz, freq=self.freq)
421-
else:
422-
return Index(self.view(np.ndarray) + other)
423-
424-
def __sub__(self, other):
425-
if isinstance(other, Index):
426-
return self.diff(other)
427-
elif isinstance(other, (datetools.DateOffset, timedelta)):
428-
new_values = self.astype('O') - other
429-
return DatetimeIndex(new_values, tz=self.tz, freq=self.freq)
420+
return DatetimeIndex(new_values, tz=self.tz)
430421
else:
431422
return Index(self.view(np.ndarray) + other)
432423

pandas/tseries/tests/test_resample.py

+22-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
from datetime import datetime
1+
from datetime import datetime, timedelta
22

33
import numpy as np
44

55
from pandas import Series, DataFrame, isnull, notnull
66

77
from pandas.tseries.index import date_range
8-
from pandas.tseries.offsets import Minute
8+
from pandas.tseries.offsets import Minute, bday
99
from pandas.tseries.period import period_range
1010
from pandas.tseries.resample import DatetimeIndex, TimeGrouper
1111
import pandas.tseries.offsets as offsets
@@ -133,6 +133,26 @@ def test_resample_basic(self):
133133
self.assertEquals(result.irow(1), s['1/4/2005'])
134134
self.assertEquals(result.irow(5), s['1/10/2005'])
135135

136+
def test_resample_loffset(self):
137+
rng = date_range('1/1/2000 00:00:00', '1/1/2000 00:13:00', freq='min')
138+
s = Series(np.random.randn(14), index=rng)
139+
result = s.resample('5min', how='mean', closed='right', label='right',
140+
loffset=timedelta(minutes=1))
141+
idx = date_range('1/1/2000', periods=4, freq='5min')
142+
expected = Series([s[0], s[1:6].mean(), s[6:11].mean(), s[11:].mean()],
143+
index=idx + timedelta(minutes=1))
144+
assert_series_equal(result, expected)
145+
146+
# from daily
147+
dti = DatetimeIndex(start=datetime(2005,1,1), end=datetime(2005,1,10),
148+
freq='D')
149+
ser = Series(np.random.rand(len(dti)), dti)
150+
151+
# to weekly
152+
result = ser.resample('w-sun', how='last')
153+
expected = ser.resample('w-sun', how='last', loffset=-bday)
154+
self.assertEqual(result.index[0] - bday, expected.index[0])
155+
136156
def test_resample_upsample(self):
137157
# from daily
138158
dti = DatetimeIndex(start=datetime(2005,1,1), end=datetime(2005,1,10),

0 commit comments

Comments
 (0)