pandas - 在groupby中添加最后3个元素的平均值列

时间:2016-09-23 16:01:41

标签: python pandas

我有一个包含多个列的数据框,我按其排序,按索引分组并计算每一行与组中下一行之间的差异。接下来我想添加一个最后3个差异的方法列。例如:

index  A  B    A_diff  B_diff    A_diff_last3mean    B_diff_last3mean 
1111   1  2      0       0               NaN              NaN
1111   1  2      0       0               NaN              NaN                 
1111   2  4      1       2               0.33             0.67
1111   4  6      2       2                1               1.33
2222   5  7     NaN     NaN              NaN              NaN #index changed
2222   2  8     -3       1               NaN              NaN 

我设法使用

创建了这样的列
df=df.join(df.groupby(['index'],sort=False,as_index=False).diff(),rsuffix='_diff')
y=df.groupby(['index'],sort=False,as_index=False).nth([-1,-2,-3])
z=y.groupby(['index'],sort=False,as_index=False).mean()

但是这会创建一个聚合的数据框,我需要将这些值合并到原始数据框中。我试过.transform()函数并没有成功。真的很感谢你的帮助。

1 个答案:

答案 0 :(得分:1)

import io
import pandas as pd

data = io.StringIO('''\
group  A  B
1111   1  2
1111   1  2
1111   2  4
1111   4  6
2222   5  7
2222   2  8
''')
df = pd.read_csv(data, delim_whitespace=True)

diff = (df.groupby('group')
          .diff()
          .fillna(0)
          .add_suffix('_diff'))
df = df.join(diff)

last3mean = (df.groupby('group')[diff.columns]
               .rolling(3).mean()  
               .reset_index(drop=True)
               .add_suffix('_last3mean'))
df = df.join(last3mean)
print(df)

输出:

   group  A  B  A_diff  B_diff  A_diff_last3mean  B_diff_last3mean
0   1111  1  2     0.0     0.0               NaN               NaN
1   1111  1  2     0.0     0.0               NaN               NaN
2   1111  2  4     1.0     2.0          0.333333          0.666667
3   1111  4  6     2.0     2.0          1.000000          1.333333
4   2222  5  7     0.0     0.0               NaN               NaN
5   2222  2  8    -3.0     1.0               NaN               NaN

注意:

  • 虽然index是完全有效的列名,但pandas DataFrames也有索引。为避免混淆,我已将该列重命名为group

  • 在您想要的输出中,您似乎已填充NaNA_diffB_diff1111,但不是2222 {1}}。代码段中的第一行不会执行此类填充。我在.fillna(0)的定义中填写了所有内容 - diff,但如果您愿意,可以删除它。