简体   繁体   中英

Convert Pandas DatetimeIndex to fractional day of year

Is there an easy way to convert a DatetimeIndex to an array of day of years, including a fraction for the hour, minute, etc. components?

For example, converting pd.date_range("2014-01-01 00:00", periods=4, freq="12H") should give me [1.0, 1.5, 2.0, 2.5] .

This requires 0.15.0 for the Timedelta functionaility. This will have full precision of your dates.

In [19]: s
Out[19]: 
<class 'pandas.tseries.index.DatetimeIndex'>
[2014-01-01 00:00:00, ..., 2014-01-02 12:00:00]
Length: 4, Freq: 12H, Timezone: None

In [21]: s-s[0]
Out[21]: 
<class 'pandas.tseries.tdi.TimedeltaIndex'>
['0 days 00:00:00', ..., '1 days 12:00:00']
Length: 4, Freq: None

In [22]: ((s-s[0]) / pd.Timedelta(1.0,unit='D')) + 1
Out[22]: Float64Index([1.0, 1.5, 2.0, 2.5], dtype='float64')

Dividing by a TimedeltaIndex by a Timedelta gives you a (float) fraction. Dates are 0 based so we add back 1.

The above 'assumes' that all of the dates are in the same year. Here is a more robust way to do this (datetimeindex subtraction is not currently directly supported)

In [53]: pd.TimedeltaIndex(s.asi8-s.to_period('A').to_timestamp().asi8)
Out[53]: 
<class 'pandas.tseries.tdi.TimedeltaIndex'>
['0 days 00:00:00', ..., '1 days 12:00:00']
Length: 4, Freq: None

I'm not sure if there are builtin methods to achieve this more neatly, but you can do:

dr = pd.date_range("2014-01-01 00:00", periods=4, freq="12H")
dr.dayofyear + dr.hour / 24.0
Out[8]: array([ 1. ,  1.5,  2. ,  2.5])

Unfortunately with this approach I think you'll have to create enough terms to get to the precision you want, eg to include minutes it would be:

dr.dayofyear + dr.hour / 24.0 + dr.minute / (24.0 * 60)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM