【问题标题】:pandas grouped weighted average with weights from records and values from column namespandas groupby 加权平均值,来自记录的权重和来自列名的值
【发布时间】:2019-08-27 13:42:34
【问题描述】:

我想计算一个分组加权平均值,其中权重显示为行,要平均的值显示为列名:

df_dict= {1: {0: 10, 1: 15, 2: 50, 3: 10, 4: 44},
 4: {0: 12, 1: 15, 2: 48, 3: 12, 4: 63},
 7.5: {0: 17, 1: 23, 2: 99, 3: 20, 4: 66},
 90: {0: 25, 1: 18, 2: 102, 3: 17, 4: 10},
 'grouping': {0: '38', 1: '38', 2: '38', 3: '86', 4: '48'}}

df = pd.DataFrame(df_dict)
display(df)

df.groupby(['grouping']).sum().reset_index()

给出:

但我不确定如何有效地计算加权平均值。使用 numpy Weighted average using numpy.average 可能是一种选择。但这意味着df.apply 是一个没有得到很好优化的自定义函数。

有没有更好的办法?

编辑

即有没有更好的晒黑方法:

df = df.groupby(['grouping']).sum().reset_index()
display(df)

def wavg(x):
    values = x.drop('grouping')
    values = values.reset_index()
    values.columns = ['value', 'weight']
    return np.average(list(values.value),
                      weights=list(values.weight))
df['wavg_location'] = df.apply(wavg, axis=1)

【问题讨论】:

    标签: python pandas group-by weighted-average


    【解决方案1】:

    这里不需要reset_index()。

    df_raw = df.groupby(['grouping']).sum()
    

    我们可以在不调用 np.average() 的情况下进行加权求和

    df = df_raw.copy()
    df['wavg_location'] = (df * df.columns).sum(axis=1) / df.sum(axis=1)
    

    我在 Jupyter notebook 中计时了两种不同的方法:

    for i in range(100):
        df = df_raw.reset_index()
        df['wavg_location'] = df.apply(wavg, axis=1)
    

    在 712 毫秒内执行

    for i in range(100):
        df = df_raw.copy()
        df['wavg_location'] = (df * df.columns).sum(axis=1) / df.sum(axis=1)
    

    在 293 毫秒内执行

    【讨论】:

      猜你喜欢
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 2021-06-26
      相关资源
      最近更新 更多