使用另一列的 groupby() 对一列的绝对值求和

Sum absolute values of one column using a groupby() of another column

我有以下名为 df 的玩具 DataFrame:

df = pd.DataFrame({'foo' : ['red', 'red', 'red', 'blue', 'blue', 'blue', 'green', 'green', 'green'], 
                     'bar'  : [10, -5, 7, 14, 20, 3, 40, -100, 75]})

foo    bar   
red     10
red     -5
red     7
blue    14
blue    -20
blue    3 
green   40
green   -100
green   75

我想使用 foo 列的 groupby()bar 列的 绝对值 求和。这是我的尝试:

df['baz'] = df.groupby('foo').bar.apply(lambda x: x.abs().sum())

我希望看到以下内容:

foo    bar     baz
red     10     22
red     -5     22
red     7      22
blue    14     37
blue    -20    37
blue    3      37
green   40     215
green   -100   215
green   75     215

不幸的是,我在新创建的 baz 列中得到 NaN

为什么这种方法会产生 NaN 值?另外(尽管我的代码中存在错误),是否有更优雅(即更 Pythonic)的方式来做到这一点?

pandas 自动对齐 index,因此您的代码不起作用,因为 groupby 结果的 index 与原始数据帧的索引不同。因此,它 returns nan.

话虽如此,您可以使用 set_index() 将索引设置为 'foo' 列,然后重试您的代码:

df.set_index('foo',inplace=True)
df['baz'] = df.groupby('foo').bar.apply(lambda x: x.abs().sum())

print(df)

       bar  baz
foo            
red     10   22
red     -5   22
red      7   22
blue    14   37
blue    20   37
blue     3   37
green   40  215
green -100  215
green   75  215

一种更 pythonic 的方式,正如你所说,我认为是使用 transform,而不是设置 index 并扭曲你的原始数据框。因此,我的建议是保持数据框不变,并将代码更改为:

df['baz'] = df.groupby('foo').bar.transform(lambda x: x.abs().sum())

print(df)

     foo  bar  baz
0    red   10   22
1    red   -5   22
2    red    7   22
3   blue   14   37
4   blue   20   37
5   blue    3   37
6  green   40  215
7  green -100  215
8  green   75  215

试试

df['baz'] = df.bar.abs().groupby(df['foo']).transform('sum')