快速计算平均值并排除一个元素

3
假设我有一个数据帧:
df = pd.DataFrame(data={'group_id': [1, 1, 1, 1, 2, 2, 2, 2], 
    'A': [24.0, 12.0, 23.0, 22.0, 44.0, 55.0, 52.0, 48.0],
    'B': [23.0, 15.0, 22.0, 21.0, 65.0, 53.0, 53.0, 54.0]})

对于数据帧中的每个索引,我想计算所属组(由组ID指定)在不包含该索引的情况下的平均值。
我开始使用两个for循环,通过使用apply函数提高了速度。
def func(x):
    df = x.copy()
    for row in x.itertuples():
        df.loc[row[0], :] = x.loc[x.index != row[0], :].mean()

    return df

df.groupby('group_id')['A', 'B'].apply(func)

所需输出为:
                    A          B
group_id                        
1        0  19.000000  19.333333
         1  23.000000  22.000000
         2  19.333333  19.666667
         3  19.666667  20.000000
2        4  51.666667  53.333333
         5  48.000000  57.333333
         6  49.000000  57.333333
         7  50.333333  57.000000

有没有更快的方法来计算这个?

2个回答

2
使用 transform。获取 sumcount
g = df.groupby('group_id')
sums = g.transform('sum')
counts = g.transform('count')

df[['A', 'B']].mul(-1).add(sums).div(counts - 1)

           A          B
0  19.000000  19.333333
1  23.000000  22.000000
2  19.333333  19.666667
3  19.666667  20.000000
4  51.666667  53.333333
5  48.000000  57.333333
6  49.000000  57.333333
7  50.333333  57.000000

0

首先,通过形成计数和索引总和的表格来整合数据(如果索引是连续或密集的,则使用数组;否则使用字典)。

创建表格后(对于M个不同的索引,大约需要O(M)次操作),累加只需要一次遍历即可完成O(N)次加法运算。

然后计算总和和总计数(O(M)次加法运算)。

最后,对于每个索引,减去相应的每个索引总和和平均值。

总成本将类似于O(N + M),与初始解决方案中的O(N²)进行比较。

如果组足够大,则此方法将是值得的。


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