【问题标题】:Sum absolute values of one column using a groupby() of another column使用另一列的 groupby() 对一列的绝对值求和
【发布时间】:2022-01-25 23:19:34
【问题描述】:

我有以下玩具 DataFrame,名为 df

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)的方式来做到这一点?

【问题讨论】:

  • 目前无法测试; df['baz'] = df.groupby('bar').abs().sum().reset_index()。可能是一厢情愿

标签: python pandas pandas-groupby


【解决方案1】:

试试

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

【讨论】:

    【解决方案2】:

    pandas 自动与index 对齐,因此您的代码不起作用,因为您的groupby 结果的index 与原始数据框的索引不同。因此,它返回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
    

    【讨论】:

    • 真的有必要为此使用apply吗?如果是为了abs(),如果df足够大,制作一个临时列可能仍然更便宜
    • df 不大(~5000 行)。
    • 同意@roganjosh,如果可以避免apply,最好避免。我相信这里的关键是使用transform,因为它非常适合这种类型的操作。如果速度和效率对您来说非常重要,我认为 Beny 的回答是正确的。我的意图是详细说明一下。
    猜你喜欢
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-23
    • 2011-07-22
    相关资源
    最近更新 更多