首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按加权平均分组,允许零值权重

按加权平均分组,允许零值权重
EN

Stack Overflow用户
提问于 2019-08-12 09:21:04
回答 1查看 719关注 0票数 0

我想取组中列的加权平均数,如下所示

代码语言:javascript
复制
import pandas as pd
import numpy as np

df = pd.DataFrame({'group': ['A', 'A', 'A', 'B', 'B', 'B'],
                   'value': [0.4, 0.3, 0.2, 0.4, 0.3, 0.2],
                   'weight': [2, 2, 4, 3, 1, 2]})

df_grouped = df.groupby('group')[['value', 'weight']].apply(lambda x: sum(x['value']*x['weight'])/sum(x['weight']))

df_grouped
Out[17]: 
group
A    0.275000
B    0.316667
dtype: float64

到目前为止一切都很好。但是,在某些情况下,例如,权重之和为零。

代码语言:javascript
复制
df = pd.DataFrame({'group': ['A', 'A', 'A', 'B', 'B', 'B'],
                   'value': [0.4, 0.3, 0.2, 0.4, 0.3, 0.2],
                   'weight': [1, 2, 3, 0, 0, 0]})

在这种情况下,我想取一个简单的平均值。由于除以零,上述表达式显然失败。

我目前使用的方法是,在权重之和为1的地方,将权重替换为1。

代码语言:javascript
复制
df_temp = df.groupby('group')['weight'].transform('sum').reset_index()
df['new_weight'] = np.where(df_temp['weight']==0, 1, df['weight'])

df_grouped = df.groupby('group')[['value', 'new_weight']].apply(lambda x: sum(x['value']*x['new_weight'])/sum(x['new_weight']))

这是一个好的解决方案。但是,这能通过一条线来实现吗?比如某些特殊的功能?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-12 09:54:21

如果需要在一行中完成,可以使用lambda中的三元操作符检查Group是否等于零,如下所示。如果组之和为零,则使用正则平均值。

代码语言:javascript
复制
df.groupby('group')[['value', 'weight']].apply(lambda x:sum(x['value'])/len(x['weight'])  if (sum(x['weight'])) == 0 else sum(x['value']*x['weight'])/sum(x['weight']))

    group
    A    0.266667
    B    0.300000
    dtype: float64

上述代码段的常规平均计算可以进一步缩小如下。

代码语言:javascript
复制
df.groupby('group')[['value', 'weight']].apply(lambda x:x['value'].mean() if (sum(x['weight'])) == 0 else sum(x['value']*x['weight'])/sum(x['weight']))

但是,我认为这种类型的一行程序降低了代码的可读性。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57458523

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档