使用另一列的 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')
我有以下名为 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')