My question is similar to this and that but neither answer works for me.
I have a dataframe of users and user survey responses. Each survey response is a assigned a weight which is a fractional number (like 1.532342). Each user responds with ~20 scores, in this example shown as scoreA
and scoreB
.
user | weight | scoreA | scoreB |
---|---|---|---|
1 | 2 | 3 | 1 |
1 | 1 | 5 | 3 |
1 | 0.5 | 7 | 5 |
2 | 0.5 | 8 | 6 |
2 | 1 | 9 | 7 |
2 | 0.5 | 8 | 6 |
It's trivial to compute the average unweighted score for each column by way of scores.groupby('user').mean()
but I'm struggling to compute the weighted score.
df = pd.DataFrame({
'weight': [ 2, 1, 0.5, 0.5,1,0.5],
'scoreA': [3,5,7, 8,9,8],
'scoreB': [1,3,5, 6,7,6]
}, index=pd.Index([1,1,1,2,2,2],name='user'))
scores = df[['scoreA', 'scoreB']]
weights = df.weight
scores.groupby('user').mean()
>>> scoreA scoreB
user
1 5.000000 3.000000
2 8.333333 6.333333
scores.groupby('user').agg(lambda x: np.average(x, weights=weights)
>>> TypeError: Axis must be specified when shapes of a and weights differ.
What I want to output is:
df.drop(columns='weight').mul(df.weight,axis=0).groupby('user').sum().div(df.weight.groupby('user').sum(),axis=0)
scoreA scoreB
user
1 4.142857 2.142857
2 8.500000 6.500000