Reputation: 2014
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
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
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
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