Skip to content

Commit 87bffb3

Browse files
committed
Merge pull request #1140 from changhiskhan/loffset
Implement loffset parameter in resample, close #1127
2 parents 3418cc8 + e08f299 commit 87bffb3

File tree

5 files changed

+36
-8
lines changed

5 files changed

+36
-8
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
@@ -158,7 +160,8 @@ def asfreq(self, freq, method=None, how=None):
158160
return asfreq(self, freq, method=method, how=how)
159161

160162
def resample(self, rule, how='mean', axis=0, as_index=True,
161-
fill_method=None, closed='right', label='right', kind=None):
163+
fill_method=None, closed='right', label='right', kind=None,
164+
loffset=None):
162165
"""
163166
Convenience method for frequency conversion and resampling of regular
164167
time-series data.
@@ -174,6 +177,8 @@ def resample(self, rule, how='mean', axis=0, as_index=True,
174177
label : {'right', 'left'}, default 'right'
175178
Which bin edge label to label bucket with
176179
as_index : see synonymous argument of groupby
180+
loffset : timedelta
181+
Adjust the resampled time labels
177182
"""
178183
from pandas.tseries.resample import TimeGrouper
179184

@@ -193,6 +198,9 @@ def resample(self, rule, how='mean', axis=0, as_index=True,
193198
# upsampling
194199
result = self.reindex(grouper.binner[1:], method=fill_method)
195200

201+
if isinstance(loffset, (DateOffset, timedelta)):
202+
if len(result.index) > 0:
203+
result.index = result.index + loffset
196204
return result
197205

198206
def first(self, offset):

pandas/tests/test_index.py

+5
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,13 @@ def test_add(self):
221221
tm.assert_contains_all(self.strIndex, secondCat)
222222
tm.assert_contains_all(self.dateIndex, firstCat)
223223

224+
def test_timedelta(self):
224225
# this is valid too
225226
shifted = self.dateIndex + timedelta(1)
227+
back = shifted + timedelta(-1)
228+
self.assert_(tm.equalContents(self.dateIndex, back))
229+
self.assertEqual(shifted.freq, self.dateIndex.freq)
230+
self.assertEqual(shifted.freq, back.freq)
226231

227232
def test_append_multiple(self):
228233
index = Index(['a', 'b', 'c', 'd', 'e', 'f'])

pandas/tseries/index.py

-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ class DatetimeIndex(Int64Index):
150150
__le__ = _dt_index_cmp('__le__')
151151
__ge__ = _dt_index_cmp('__ge__')
152152

153-
__add__ = _dt_index_op('__add__')
154153
__sub__ = _dt_index_op('__sub__')
155154

156155
# structured array cache for datetime fields

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),

pandas/util/testing.py

-4
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,6 @@ def makeFloatIndex(k):
163163
values = sorted(np.random.random_sample(k)) - np.random.random_sample(1)
164164
return Index(values * (10 ** np.random.randint(0, 9)))
165165

166-
def makeDateIndex(k):
167-
dates = list(bdate_range(datetime(2000, 1, 1), periods=k))
168-
return Index(dates)
169-
170166
def makeFloatSeries():
171167
index = makeStringIndex(N)
172168
return Series(randn(N), index=index)

0 commit comments

Comments
 (0)