用于计算组中加权平均值的 lambda 函数

lambda function to calculate weighted average in a group by

我编写了以下代码行:

DF.groupby(["Name"], as_index=False).agg({"A": lambda x:sum(abs(x)) ,'B': 'first'}).round(2)

带 DF 输出:

Name A B
Test 6 3
Test -3

给出以下输出:

Name A B
Test 9 3

我将如何获得以下输出:

Name A B
Test 9 1

1 由以下公式给出:

((6*3)+(-3*3))/9 = 1

想知道是否可以通过

直接在组内执行此操作

最大的 DF##

Name    A   B
Test    3   3
Test    -3  2
Test    4   4
Test    5   5
Test1   6   7
Test1   7   8

输出将是:

Name A B
Test 15 2.93
Test1 13 7.54

注:

A = Absolute value : Test = 3 + |-3| + 4 + 5 = 15
B = Weighted Average : Test = ( 3*3 + (-3)*2 + 4*4 + 5*5 ) / 15 = 2.93

您可以使用 assign 修改列,然后使用 groupby.sum 求总计;然后 assign 再次找到比率:

out = df.assign(A=df['A'].abs(), B=df['A']*df['B']).groupby('Name', as_index=False).sum().assign(B=lambda x:x['B']/x['A'])

输出:

    Name   A         B
0   Test  15  2.933333
1  Test1  13  7.538462

我还找到了另一种方法:

def fn(group):
    group['B'] = group['B'] * group['A'] / abs(group['A']).sum()
    group['A'] = abs(group['A'])
    return group

d_agg = {'A':'sum',
         'B':'sum'
    }

DF.groupby(["Name"], as_index=False).apply(fn).groupby('Name').agg(d_agg).round(2)

您还可以执行以下操作:

def fn(group):
    g = pd.Series({'A':abs(group['A']).sum()})
    g['B'] = (group['B'] * group['A']).sum() / g['A']
    return g
out = df.groupby(["Name"], as_index=False).apply(fn)