Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating pandas timeseries with a month but not a year

Using pandas I can index a timeseries using a datetime object (with a month and day) and get the value for a period, e.g.:

from pandas import *
ts = TimeSeries([41,45,48],[Period('2012'),Period('2013'),Period('2014')])
print ts[datetime(2013,05,17)]

Is there any way to define a period with a month but without a year? I have an average annual profile with a monthly frequency, that I'd like to be able to index by month/day, eg:

ts = TimeSeries(range(1,13),[Period(month=n,freq='M') for n in range(1,13)])
print ts[datetime(2013,05,17)]

The Period object doesn't seem to support this (it throws an error). Is there a better way to do this than creating the timeseries with a year, then modifying the datetime object before it's used to index the timeseries?

http://pandas.pydata.org/pandas-docs/dev/timeseries.html#period

Edit 1:

To clarify a little why I want to do this: I have a model which computes on a daily timestep. I have a variable in the model which is a datetime object representing the current day. I need to check the current day against several timeseries, some of which have a full date (year/month/day) but others which only have a month. I was hoping for something as seamless as indexing, as the timeseries/profiles are supplied by the user at runtime. I've had a go at overriding the __getitem__ method of the TimeSeries object (so that I could fix the years behind the scenes), but it seems a bit of a crazy hack.

from pandas import *

class TimeSeriesProfile(TimeSeries):
    year = 2004

    def __new__(self, *args, **kwargs):
        inst = TimeSeries.__new__(self, *args, **kwargs)
        inst.index = period_range(str(self.year)+str(inst.index[0])[4:], periods=len(inst.index), freq=inst.index.freq)
        return inst.view(TimeSeriesProfile)

    def __getitem__(self, key):
        without_year = datetime(self.year, key.month, key.day, key.hour, key.minute, key.second)
        return TimeSeries.__getitem__(self, without_year)

ts = TimeSeriesProfile(range(0, 366), period_range('1996-01-01', periods=366, freq='D'))

print ts[datetime(2008, 02, 29)]
like image 310
Snorfalorpagus Avatar asked Nov 13 '22 04:11

Snorfalorpagus


1 Answers

Try period_range:

In [65]: TimeSeries(range(1, 13), period_range('2013-01', periods=12, freq='M'))
Out[65]: 
2013-01     1   
2013-02     2   
2013-03     3   
2013-04     4   
2013-05     5   
2013-06     6   
2013-07     7   
2013-08     8   
2013-09     9   
2013-10    10  
2013-11    11  
2013-12    12  
Freq: M, dtype: int64
like image 135
waitingkuo Avatar answered Nov 14 '22 23:11

waitingkuo