Skip to content

Commit 0523e7c

Browse files
committed
Merge pull request #9226 from tvyomkesh/vyom/firstpr
ENH: add to_offset method to Timedelta #9064
2 parents 8eecbbf + 2efce4e commit 0523e7c

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

doc/source/whatsnew/v0.16.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ Enhancements
9999
- Added time interval selection in get_data_yahoo (:issue:`9071`)
100100
- Added ``Series.str.slice_replace()``, which previously raised NotImplementedError (:issue:`8888`)
101101
- Added ``Timestamp.to_datetime64()`` to complement ``Timedelta.to_timedelta64()`` (:issue:`9255`)
102+
- ``tseries.frequencies.to_offset()`` now accepts ``Timedelta`` as input (:issue:`9064`)
102103

103104

104105
Performance

pandas/tseries/frequencies.py

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from datetime import datetime
1+
from datetime import datetime,timedelta
22
from pandas.compat import range, long, zip
33
from pandas import compat
44
import re
@@ -12,6 +12,7 @@
1212
import pandas.core.common as com
1313
import pandas.lib as lib
1414
import pandas.tslib as tslib
15+
from pandas.tslib import Timedelta
1516

1617
class FreqGroup(object):
1718
FR_ANN = 1000
@@ -276,9 +277,18 @@ def get_period_alias(offset_str):
276277
_legacy_reverse_map = dict((v, k) for k, v in
277278
reversed(sorted(compat.iteritems(_rule_aliases))))
278279

280+
_name_to_offset_map = {'days': Day(1),
281+
'hours': Hour(1),
282+
'minutes': Minute(1),
283+
'seconds': Second(1),
284+
'milliseconds': Milli(1),
285+
'microseconds': Micro(1),
286+
'nanoseconds': Nano(1)}
287+
279288
def to_offset(freqstr):
280289
"""
281-
Return DateOffset object from string representation
290+
Return DateOffset object from string representation or
291+
Timedelta object
282292
283293
Examples
284294
--------
@@ -298,6 +308,23 @@ def to_offset(freqstr):
298308
name, stride = stride, name
299309
name, _ = _base_and_stride(name)
300310
delta = get_offset(name) * stride
311+
312+
elif isinstance(freqstr, timedelta):
313+
delta = None
314+
freqstr = Timedelta(freqstr)
315+
try:
316+
for name in freqstr.components._fields:
317+
offset = _name_to_offset_map[name]
318+
stride = getattr(freqstr.components, name)
319+
if stride != 0:
320+
offset = stride * offset
321+
if delta is None:
322+
delta = offset
323+
else:
324+
delta = delta + offset
325+
except Exception:
326+
raise ValueError("Could not evaluate %s" % freqstr)
327+
301328
else:
302329
delta = None
303330
stride_sign = None

pandas/tseries/tests/test_frequencies.py

+42
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import pandas.compat as compat
1818

1919
import pandas.util.testing as tm
20+
from pandas import Timedelta
2021

2122
def test_to_offset_multiple():
2223
freqstr = '2h30min'
@@ -81,6 +82,47 @@ def test_to_offset_leading_zero():
8182
assert(result.n == -194)
8283

8384

85+
def test_to_offset_pd_timedelta():
86+
# Tests for #9064
87+
td = Timedelta(days=1, seconds=1)
88+
result = frequencies.to_offset(td)
89+
expected = offsets.Second(86401)
90+
assert(expected==result)
91+
92+
td = Timedelta(days=-1, seconds=1)
93+
result = frequencies.to_offset(td)
94+
expected = offsets.Second(-86399)
95+
assert(expected==result)
96+
97+
td = Timedelta(hours=1, minutes=10)
98+
result = frequencies.to_offset(td)
99+
expected = offsets.Minute(70)
100+
assert(expected==result)
101+
102+
td = Timedelta(hours=1, minutes=-10)
103+
result = frequencies.to_offset(td)
104+
expected = offsets.Minute(50)
105+
assert(expected==result)
106+
107+
td = Timedelta(weeks=1)
108+
result = frequencies.to_offset(td)
109+
expected = offsets.Day(7)
110+
assert(expected==result)
111+
112+
td1 = Timedelta(hours=1)
113+
result1 = frequencies.to_offset(td1)
114+
result2 = frequencies.to_offset('60min')
115+
assert(result1 == result2)
116+
117+
td = Timedelta(microseconds=1)
118+
result = frequencies.to_offset(td)
119+
expected = offsets.Micro(1)
120+
assert(expected == result)
121+
122+
td = Timedelta(microseconds=0)
123+
tm.assertRaises(ValueError, lambda: frequencies.to_offset(td))
124+
125+
84126
def test_anchored_shortcuts():
85127
result = frequencies.to_offset('W')
86128
expected = frequencies.to_offset('W-SUN')

0 commit comments

Comments
 (0)