Skip to content

Commit 8d209de

Browse files
committed
Merge pull request #7452 from sinhrks/offsets_dt64
ENH/API: offsets funcs now accepts datetime64
2 parents eb1ae6b + ff22175 commit 8d209de

File tree

4 files changed

+57
-45
lines changed

4 files changed

+57
-45
lines changed

doc/source/v0.14.1.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ Enhancements
126126

127127

128128

129-
129+
- All offsets ``apply``, ``rollforward`` and ``rollback`` can now handle ``np.datetime64``, previously results in ``ApplyTypeError`` (:issue:`7452`)
130130

131131

132132

pandas/tseries/offsets.py

+2-14
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ def wrapper(self, other):
4545
return tslib.NaT
4646
if type(other) == date:
4747
other = datetime(other.year, other.month, other.day)
48+
elif isinstance(other, np.datetime64):
49+
other = as_timestamp(other)
4850

4951
result = func(self, other)
5052

@@ -555,20 +557,6 @@ def apply(self, other):
555557

556558
return as_timestamp(result)
557559

558-
elif isinstance(other, np.datetime64):
559-
date_in = other
560-
np_day = date_in.astype('datetime64[D]')
561-
np_time = date_in - np_day
562-
563-
np_incr_dt = np.busday_offset(np_day, self.n, roll=roll,
564-
busdaycal=self.busdaycalendar)
565-
result = np_incr_dt + np_time
566-
567-
if self.offset:
568-
result = result + self.offset
569-
570-
return as_timestamp(result)
571-
572560
elif isinstance(other, (timedelta, Tick)):
573561
return BDay(self.n, offset=self.offset + other,
574562
normalize=self.normalize)

pandas/tseries/tests/test_offsets.py

+35-30
Original file line numberDiff line numberDiff line change
@@ -222,19 +222,20 @@ def _check_nanofunc_works(self, offset, funcname, dt, expected):
222222
self.assertEqual(func(t1), expected)
223223

224224
def test_apply(self):
225-
dt = datetime(2011, 1, 1, 9, 0)
225+
sdt = datetime(2011, 1, 1, 9, 0)
226+
ndt = np.datetime64('2011-01-01 09:00Z')
226227

227228
for offset in self.offset_types:
228-
expected = self.expecteds[offset.__name__]
229-
230-
if offset == Nano:
231-
self._check_nanofunc_works(offset, 'apply', dt, expected)
232-
else:
233-
self._check_offsetfunc_works(offset, 'apply', dt, expected)
229+
for dt in [sdt, ndt]:
230+
expected = self.expecteds[offset.__name__]
231+
if offset == Nano:
232+
self._check_nanofunc_works(offset, 'apply', dt, expected)
233+
else:
234+
self._check_offsetfunc_works(offset, 'apply', dt, expected)
234235

235-
expected = Timestamp(expected.date())
236-
self._check_offsetfunc_works(offset, 'apply', dt, expected,
237-
normalize=True)
236+
expected = Timestamp(expected.date())
237+
self._check_offsetfunc_works(offset, 'apply', dt, expected,
238+
normalize=True)
238239

239240
def test_rollforward(self):
240241
expecteds = self.expecteds.copy()
@@ -261,17 +262,19 @@ def test_rollforward(self):
261262
'Micro': Timestamp('2011-01-01 00:00:00')}
262263
norm_expected.update(normalized)
263264

264-
dt = datetime(2011, 1, 1, 9, 0)
265-
for offset in self.offset_types:
266-
expected = expecteds[offset.__name__]
265+
sdt = datetime(2011, 1, 1, 9, 0)
266+
ndt = np.datetime64('2011-01-01 09:00Z')
267267

268-
if offset == Nano:
269-
self._check_nanofunc_works(offset, 'rollforward', dt, expected)
270-
else:
271-
self._check_offsetfunc_works(offset, 'rollforward', dt, expected)
272-
expected = norm_expected[offset.__name__]
273-
self._check_offsetfunc_works(offset, 'rollforward', dt, expected,
274-
normalize=True)
268+
for offset in self.offset_types:
269+
for dt in [sdt, ndt]:
270+
expected = expecteds[offset.__name__]
271+
if offset == Nano:
272+
self._check_nanofunc_works(offset, 'rollforward', dt, expected)
273+
else:
274+
self._check_offsetfunc_works(offset, 'rollforward', dt, expected)
275+
expected = norm_expected[offset.__name__]
276+
self._check_offsetfunc_works(offset, 'rollforward', dt, expected,
277+
normalize=True)
275278

276279
def test_rollback(self):
277280
expecteds = {'BusinessDay': Timestamp('2010-12-31 09:00:00'),
@@ -315,18 +318,20 @@ def test_rollback(self):
315318
'Micro': Timestamp('2011-01-01 00:00:00')}
316319
norm_expected.update(normalized)
317320

318-
dt = datetime(2011, 1, 1, 9, 0)
319-
for offset in self.offset_types:
320-
expected = expecteds[offset.__name__]
321+
sdt = datetime(2011, 1, 1, 9, 0)
322+
ndt = np.datetime64('2011-01-01 09:00Z')
321323

322-
if offset == Nano:
323-
self._check_nanofunc_works(offset, 'rollback', dt, expected)
324-
else:
325-
self._check_offsetfunc_works(offset, 'rollback', dt, expected)
324+
for offset in self.offset_types:
325+
for dt in [sdt, ndt]:
326+
expected = expecteds[offset.__name__]
327+
if offset == Nano:
328+
self._check_nanofunc_works(offset, 'rollback', dt, expected)
329+
else:
330+
self._check_offsetfunc_works(offset, 'rollback', dt, expected)
326331

327-
expected = norm_expected[offset.__name__]
328-
self._check_offsetfunc_works(offset, 'rollback',
329-
dt, expected, normalize=True)
332+
expected = norm_expected[offset.__name__]
333+
self._check_offsetfunc_works(offset, 'rollback',
334+
dt, expected, normalize=True)
330335

331336
def test_onOffset(self):
332337

vb_suite/timeseries.py

+19
Original file line numberDiff line numberDiff line change
@@ -285,14 +285,33 @@ def date_range(start=None, end=None, periods=None, freq=None):
285285
setup = common_setup + """
286286
import datetime as dt
287287
import pandas as pd
288+
import numpy as np
288289
289290
date = dt.datetime(2011,1,1)
291+
dt64 = np.datetime64('2011-01-01 09:00Z')
292+
293+
day = pd.offsets.Day()
294+
year = pd.offsets.YearBegin()
290295
cday = pd.offsets.CustomBusinessDay()
291296
cme = pd.offsets.CustomBusinessMonthEnd()
292297
"""
298+
timeseries_day_incr = Benchmark("date + day",setup)
299+
300+
timeseries_day_apply = Benchmark("day.apply(date)",setup)
301+
302+
timeseries_year_incr = Benchmark("date + year",setup)
303+
304+
timeseries_year_apply = Benchmark("year.apply(date)",setup)
305+
293306
timeseries_custom_bday_incr = \
294307
Benchmark("date + cday",setup)
295308

309+
timeseries_custom_bday_apply = \
310+
Benchmark("cday.apply(date)",setup)
311+
312+
timeseries_custom_bday_apply_dt64 = \
313+
Benchmark("cday.apply(dt64)",setup)
314+
296315
# Increment by n
297316
timeseries_custom_bday_incr_n = \
298317
Benchmark("date + 10 * cday",setup)

0 commit comments

Comments
 (0)