Python Pandas:计算组内移动平均

Python Pandas: Calculate moving average within group

我有一个包含 100 个对象的时间序列的数据框:

object  period  value 
1       1       24
1       2       67
...
1       1000    56
2       1       59
2       2       46
...
2       1000    64
3       1       54
...
100     1       451
100     2       153
...
100     1000    21

我想为 value 列计算 window 10 的移动平均线。我想我必须做类似

的事情
df.groupby('object').apply(lambda ~calculate MA~) 

然后把这个Series按对象合并到原来的dataframe?无法弄清楚确切的命令

您可以将 rollingtransform 一起使用:

df['moving'] = df.groupby('object')['value'].transform(lambda x: x.rolling(10, 1).mean())

rolling中的1是最小周期数。

您可以在 groupby 对象上直接使用 rolling 作为:

df['moving'] = df.groupby('object').rolling(10)['value'].mean()

新的 pandas 版本在使用直接分配给列时会抛出错误,因此请使用:

df['moving'] = df.groupby('object').rolling(10)['value'].mean().reset_index(drop=True)

扩展@Sandeep Kadapa 的答案:

df['moving'] = df.groupby('object').rolling(10)['value'].mean().reset_index(drop=True)

reset_index 的原因是因为在 df.groupby 之后我们得到了一个多级索引并且在赋值时我们会得到错误 TypeError: incompatible index of inserted column with frame index

创建列作为链式方法:

(
    df
        .assign(
            column_name = lambda x: 
                x
                    .groupby(['object'])['value']
                    .transform(lambda x: x.rolling(10)
                    .mean())
        )
)

如果您对多列进行分组,所提供的答案可能不会产生预期的结果。

下面应该剪掉它:

df['moving'] = df.groupby(['col_1', 'col_2', 'col_3']).rolling(10)['value'].mean().droplevel(level=[0,1,2])

这些解决方案假设数据帧以特定方式排序(按对象和时间段)。例如,如果数据按面板组织(按时间段和对象),则分配将失败。一种不考虑排序顺序的通用解决方案如下:

df.loc[:, 'value_sma_10'] = df.groupby(by='object')[['object', 'period']].rolling(window=10, min_periods=1, on='period').mean().reset_index(level='object')['value']