4

I am looking to use pd.rolling_mean in a groupby operation. I want to have in each group a rolling mean of the previous elemnets within the same group. Here is an example:

id    val
0     1
0     2
0     3
1     4
1     5
2     6

Grouping by id, this should be transformed into:

id    val
0     nan
0     1
0     1.5
1     nan
1     4
2     nan
splinter
  • 3,727
  • 8
  • 37
  • 82

2 Answers2

4

I think you need groupby with shift and rolling, window size can be set to scalar:

df['val']=df.groupby('id')['val'].apply(lambda x: x.shift().rolling(2, min_periods=1).mean())
print (df)
   id  val
0   0  NaN
1   0  1.0
2   0  1.5
3   1  NaN
4   1  4.0
5   2  NaN

Thank you 3novak for comment - you can set window size by max length of group:

f = lambda x: x.shift().rolling(df['id'].value_counts().iloc[0], min_periods=1).mean()
df['val'] = df.groupby('id')['val'].apply(f)
print (df)
   id  val
0   0  NaN
1   0  1.0
2   0  1.5
3   1  NaN
4   1  4.0
5   2  NaN
Community
  • 1
  • 1
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
  • 2
    I think OP's question may require a larger window size. 2 is sufficient for this data set, but it should be set to `df['id'].value_counts().iloc[0]`. – 3novak Mar 31 '17 at 13:30
4

I believe you want pd.Series.expanding

df.groupby('id').val.apply(lambda x: x.expanding().mean().shift())

0    NaN
1    1.0
2    1.5
3    NaN
4    4.0
5    NaN
Name: val, dtype: float64
piRSquared
  • 285,575
  • 57
  • 475
  • 624