Search code examples
pythonpandasfrequency

Convert Daily Dataframe with Multi Index to quarterly


I would like to convert my daily dataframe of stock data to a quarterly one. However, using resample did not work, because I have a multi index, so I would like my final quarterly dataframe to still contain the individual stocks (resample just summarizes all of them):

import pandas as pd
dict1 = [
        {'ticker':'jpm','date': '2016-11-27','returns': 0.2},
        {'ticker':'jpm','date': '2016-11-28','returns': 0.2},
{'ticker':'ge','date': '2016-11-27','returns': 0.2},
{'ticker':'ge','date': '2016-11-28','returns': 0.2},
{'ticker':'amzn','date': '2016-11-27','returns': 0.2},
{'ticker':'amzn','date': '2016-11-28','returns': 0.2},
]
df1= pd.DataFrame(dict1)
df1['date']      = pd.to_datetime(df1['date'])
df1=df1.set_index(['date','ticker'], drop=True)  

My final result is supposed to be:

Q42016 JPM  0.2
Q42016 GE   0.2
Q42016 AMZ  0.2

When I used resample, I get:

Q42016  0.2

Also, I am stuck with Pandas 0.18 (long story). Any help is appreciated.


Solution

  • First idea is create DatetimeIndex by convert ticker to column, then use groupby with resample:

    df1 = df1.reset_index('ticker').groupby('ticker').resample('Q').mean()
    print (df1)
                       returns
    ticker date               
    amzn   2016-12-31      0.2
    ge     2016-12-31      0.2
    jpm    2016-12-31      0.2
    

    Another solution with Grouper:

    df1 = df1.groupby([pd.Grouper(freq='Q', level='date'), 'ticker']).mean()
    print (df1)
                       returns
    date       ticker         
    2016-12-31 amzn        0.2
               ge          0.2
               jpm         0.2
    

    For quarter periods use assign with to_period and then aggregate by groupby:

    df1 = (df1.reset_index()
              .assign(date = lambda x: x['date'].dt.to_period('Q'))
              .groupby(['date','ticker'])
              .mean())
    print (df1)
                   returns
    date   ticker         
    2016Q4 amzn        0.2
           ge          0.2
           jpm         0.2