使用group-by在Pandas数据框上计算累积移动平均值

3
我可以解决这个问题,但不是用 Pythonic 的方式。给定以下数据框:
   time  rssi  key1  key2  CMA
0  0.021 -71   P     A     NaN
1  0.022 -60   Q     A     NaN
2  0.025 -56   P     B     NaN
3  0.12  -70   Q     B     NaN
4  0.167 -65   P     A     NaN
5  0.210 -55   P     B     NaN
6  0.211 -74   Q     A     NaN
7  0.213 -62   Q     B     NaN
...

逐行计算RSSI的累积移动平均值(CMA),将其放入RSSI平均列中。按key1key2分组,按时间递增迭代。这相当于计算四个CMA:(P,A)(P,B)(Q,A)(Q,B)。最后,计算出的CMA应放入CMA列中。
注意事项1: 我知道不应使用此公式计算RSSI平均值,但我不在意。 注意事项2: CMA公式为avg(n) = (avg(n-1) * (n-1) + value(n))/n 示例1: 定义了groupby()策略。
   time  rssi  key1  key2  CMA
0  0.021 -71   P     A     NaN <<-- first value can stay NaN or be default to rssi (i.e. -71)
4  0.167 -65   P     A     -68
...

示例2:

期望输出

   time  rssi  key1  key2  CMA
0  0.021 -71   P     A     NaN
1  0.022 -60   Q     A     NaN
2  0.025 -56   P     B     NaN
3  0.12  -70   Q     B     NaN
4  0.167 -65   P     A     -68
5  0.210 -55   P     B     -55.5
6  0.211 -74   Q     A     -67
7  0.213 -62   Q     B     -66
...

到目前为止,这是我能想到的。
import pandas as pd
import numpy as np
df = pd.DataFrame()
df['time'] = [0.021,0.022,0.025,0.12,0.167,0.210,0.211,0.213]
df['rssi'] = [-71,-60,-56,-70,-65,-55,-74,-62]
df['key1'] = ['P','Q','P','Q','P','P','Q','Q']
df['key2'] = ['A','A','B','B','A','B','A','B']
df["CMA"] = np.nan

for key, grp in df.groupby(['key1', 'key2']):
    i = 0
    old_index = 0
    for index, row in grp.iterrows():
        if i == 0:
            # allowed alternative
            df.at[index,'CMA'] = grp.at[index,'rssi']
            old_index = index
        else:
            df.at[index,'CMA'] = ((df.at[old_index,'CMA'] * i) + df.at[index,'rssi']) / (i+1)
            old_index = index
        i += 1

print df

这个方法是可行的,但看起来不太美观。有没有更符合python风格的方式来实现相同的功能呢?我该如何在不显式设置每个单元格值的情况下改进它呢?


这个回答解决了你的问题吗?Pandas - 带有groupby的扩展平均值 - Daemon Painter
1个回答

1

您可以使用groupby().expanding().mean()reset_index进行操作:

df['CMA'] = (df.groupby(['key1','key2'], 
                        as_index=False)['rssi']
               .expanding(min_periods=2).mean()
               .reset_index(level=0, drop=True)
            )

输出:

    time  rssi key1 key2   CMA
0  0.021   -71    P    A   NaN
1  0.022   -60    Q    A   NaN
2  0.025   -56    P    B   NaN
3  0.120   -70    Q    B   NaN
4  0.167   -65    P    A -68.0
5  0.210   -55    P    B -55.5
6  0.211   -74    Q    A -67.0
7  0.213   -62    Q    B -66.0

谢谢!你可以向我解释一下吗? - Daemon Painter
基本上,groupby()['rssi'] 通过每个唯一的键对 (key1, key2) 对系列进行分组。对于每个组,expanding().mean() 给出了滚动平均值。reset_index() 跳过了 groupby() 生成的组编号。 - Quang Hoang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接