在 Pandas 中按另一列进行加权平均。

3
我想要计算一个列中每个组的平均分数,该分数由另一列进行加权。
我将写一个示例来澄清我的目标。假设我有以下pandas数据帧:
组 #条目 分数 A 10 2 A 15 4 A 20 6 B 5 5 B 10 8
我的期望输出结果应该是:
组 平均加权分数 A 4.444 B 7
df = pd.DataFrame([['A',10,2],['A',15,4],['A',20,6],['B',5,5],['B',10,8]],columns = ['Group', '#items', 'score'])

1
所以 #Item 是加权列吗? - sammywemmy
2
这个回答解决了你的问题吗?使用pandas/dataframe计算加权平均值 - Tzane
4个回答

3
让我们开始吧:
f = lambda x: sum(x['#items'] * x['score']) / sum(x['#items'])

df.groupby('Group').apply(f)

2

按照 Group 列对数据框进行分组,然后使用 nump.average 函数计算加权平均值,其中平均值使用 score 列的值,权重使用 # items。您可以调用 to_frame 并传递新列名称来创建一个由结果系列组成的数据框。

(
    df.groupby('Group')
    .apply(lambda x: np.average(x['score'], weights=x['# items']))
    .to_frame('avg_weighted_score')
    )
       avg_weighted_score
Group                    
A                4.444444
B                7.000000

2

我认为在分组和聚合之前,预先计算加权列的乘积总和可以获得更好的性能(仅是一种假设):

(df.set_index('Group')
   .assign(numerator = lambda df: df.prod(1))
   .groupby('Group')
   .pipe(lambda group: group.numerator.sum() / group['#items'].sum())
)


Group
A    4.444444
B    7.000000
dtype: float64

另一种解决方案,来自@Mozway:

groups = (df.assign(w=df['#items']
                      .mul(df['score']))
           .groupby(df['Group']) 
         )

groups['w'].sum().div(groups['#items'].sum())

Group
A    4.444444
B    7.000000
dtype: float64



1
我靠,我一直在想为什么答案不对,原来是我用错了列^^。这里有一个类似于你的版本(顺便加1),但直接使用groupby对象(如果你愿意,可以在你的答案中使用):groups = df.assign(w=df['#items'].mul(df['score'])).groupby(df['Group']) ; groups['w'].sum().div(groups['#items'].sum())。这确实比“apply”方法更快。 - mozway

1

尝试:

x = (
    df.groupby("Group")
    .apply(lambda x: np.average(x["score"], weights=x["#items"]))
    .reset_index()
    .rename(columns={0: "avg_weighted_score"})
)
print(x)

输出:

  Group  avg_weighted_score
0     A            4.444444
1     B            7.000000

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