Femto Trader
Femto Trader

Reputation: 2014

Build a Pandas pd.tseries.offsets from timedelta

I'd like to build a Pandas pd.tseries.offsets from a datetime.timedelta

In [1]: from pandas.tseries.frequencies import to_offset
In [2]: import datetime
In [3]: td = datetime.timedelta(hours=1)


In [4]: to_offset('1H')
Out [4]: <Hour>

In [5]: to_offset(td)
Out [5]: ValueError

Any (other) idea ?

Upvotes: 7

Views: 4634

Answers (3)

Little Bobby Tables
Little Bobby Tables

Reputation: 4742

This now works for pandas 23.x. I could not find when it was introduced.

from pandas.tseries.frequencies import to_offset

td = datetime.timedelta(hours=1)

to_offset('1H')
>>> <Hour>

to_offset(td)
>>> <Hour>

Upvotes: 3

elyase
elyase

Reputation: 41003

to_offset returns a pd.DateOffset. So you can directly build this object:

>>> td = datetime.timedelta(hours=1)
>>> pd.DateOffset(seconds=td.total_seconds())
<DateOffset: kwds={'seconds': 3600.0}>

>>> to_offset(pd.DateOffset(seconds=td.total_seconds()))
<DateOffset: kwds={'seconds': 3600.0}>

For a slightly nicer string representation:

>>> pd.DateOffset(days=td.days, 
                  hours=td.seconds // 3600, 
                  minutes=(td.seconds // 60) % 60)
<DateOffset: kwds={'hours': 1, 'minutes': 0, 'days': 0}>

Upvotes: 6

Ffisegydd
Ffisegydd

Reputation: 53718

This cannot be done using the to_offset function directly.

However, what you can do is convert your datetime.timedelta into the appropriate string and then pass that in as an argument.

datetime.timdeltas have two properties, td.days and td.seconds which tell you the difference in days and seconds, respectively. This is to say that the timedelta corresponding to 2 days and 15 seconds would have td.days = 2 and td.seconds = 15.

The code below will construct a string with the format "XXXDYYYS" and then pass that to to_offset. The disadvantage of this is that when you print it, it doesn't look as pretty, that is it won't say <Hour>, it'll say <3600 seconds>. But I assume you can live with that.

from pandas.tseries.frequencies import to_offset
import datetime


td = datetime.timedelta(days=4, hours=1, seconds=12)

s = '{td.days}D{td.seconds}S'.format(td=td)
print(s)
# 4D3612S

offset = to_offset(s)
print(offset)
# <349212 * Seconds>

And as a nice little function:

def td_to_offset(td):
    return to_offset('{td.days}D{td.seconds}S'.format(td=td))

Upvotes: 1

Related Questions