Lets assume I have a dataframe
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]})
for every index in the dataframe I would like to calculate the mean of the group (as specified by group id) without this index included.
I started with two for loops and improved speed by using 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)
The desired output is
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
Is there a faster way to compute this?
Use transform. Get sum and count
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With