Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pandas count values for last 7 days from each date

There are two Dataframes. First is like this:

print df1

        id        date    month  is_buy
     0  17  2015-01-16  2015-01       1
     1  17  2015-01-26  2015-01       1
     2  17  2015-01-27  2015-01       1
     3  17  2015-02-11  2015-02       1
     4  17  2015-03-14  2015-03       1
     5  18  2015-01-28  2015-01       1
     6  18  2015-02-12  2015-02       1
     7  18  2015-02-25  2015-02       1
     8  18  2015-03-04  2015-03       1

In second data frame there are some aggregated data by month from the first one:

df2 = df1[df1['is_buy'] == 1].groupby(['id', 'month']).agg({'is_buy': np.sum})

print df2

        id    month       buys
     0  17  2015-01          3
     1  17  2015-02          1
     2  17  2015-03          1
     3  18  2015-01          1
     4  18  2015-02          2
     5  18  2015-03          1

I'm trying to get new df2 column named 'last_week_buys' with aggregated buys by last 7 days from first day of each df1['month']. In other words, I want to get this:

        id    month       buys    last_week_buys
     0  17  2015-01          3               NaN
     1  17  2015-02          1                 2
     2  17  2015-03          1                 0
     3  18  2015-01          1               NaN
     4  18  2015-02          2                 1
     5  18  2015-03          1                 1

Are there any ideas to get this column?

like image 895
Artem Betley Avatar asked Nov 25 '15 10:11

Artem Betley


1 Answers

This can be done with a bit of date manipulation magic and group-bys:

# datetimeindex makes convenient manipulations
date = pd.DatetimeIndex(df1['date'])

# compute df2: totals by month
df1['month'] = date.to_period('M')
df2 = df1[df1['is_buy'] == 1].groupby(['id', 'month']).sum()

# compute df3: totals by last seven days
from datetime import timedelta
is_last_seven = date.to_period('M') != (date + timedelta(days=7)).to_period('M')
df3 = df1[(df1['is_buy'] == 1) & is_last_seven].groupby(['id', df1.month + 1]).sum()

# join the results
result = df2.join(df3, rsuffix='_last_seven')

Here is the result:

>>> print(result)

            is_buy  is_buy_last_seven
id month                             
17 2015-01       3                NaN
   2015-02       1                  2
   2015-03       1                NaN
18 2015-01       1                NaN
   2015-02       2                  1
   2015-03       1                  1

You can then fill the NaN values as you desire.

like image 72
jakevdp Avatar answered Oct 04 '22 04:10

jakevdp