【问题标题】:How to sum negative and positive values separately when using groupby in pandas?在熊猫中使用groupby时如何分别对负值和正值求和?
【发布时间】:2016-02-20 05:34:17
【问题描述】:

如何在pandas 中对正负值进行不同的求和并将它们放在positivenegative 列中?

我有如下数据框:

df = pandas.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
                   'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
                   'C' : np.random.randn(8), 'D' : np.random.randn(8)})

输出如下:

df
     A      B         C         D
0  foo    one  0.374156  0.319699
1  bar    one -0.356339 -0.629649
2  foo    two -0.390243 -1.387909
3  bar  three -0.783435 -0.959699
4  foo    two -1.268622 -0.250871
5  bar    two -2.302525 -1.295991
6  foo    one -0.968840  1.247675
7  foo  three  0.482845  1.004697

我使用下面的代码得到否定:

df['negative'] = df.groupby('A')['C'].apply(lambda x: x[x<0].sum()).reset_index()]

但问题是,当我想将它添加到名为 negativedataframe 列之一时,它会给出错误:

ValueError: Wrong number of items passed 2, placement implies 1

我再次知道groupby 已返回多个列并且无法将其分配给df['negatives'] 的内容,但我不知道如何解决这部分问题。我也需要有积极的col。

期望的结果是:

    A      Positive   Negative
0  foo     0.374156  -0.319699
1  bar     0.356339  -0.629649

什么是问题的正确解决方案?

【问题讨论】:

    标签: python pandas group-by sum dataframe


    【解决方案1】:
    In [14]:
    df.groupby(df['A'])['C'].agg([('negative' , lambda x : x[x < 0].sum()) , ('positive' , lambda x : x[x > 0].sum())])
    Out[14]:
         negative   positive
    A       
    bar -1.418788   2.603452
    foo -0.504695   2.880512
    

    【讨论】:

    • 当我通过A 分组时,我希望在结果中只看到foobar。你的解决方案不符合这一点。我不需要列 B 如果它被删除我会同意的
    • 发布你想要的结果的样本,最好不要生成随机数据,这样我们可以确保我们得到相同的结果
    • 我已在问题中添加了The desired outcome would 部分,请查看。
    【解决方案2】:

    您可以在Adf['C'] &gt; 0groupby,然后unstack 结果:

    >>> right = df.groupby(['A', df['C'] > 0])['C'].sum().unstack()
    >>> right = right.rename(columns={True:'positive', False:'negative'})
    >>> right
    C    negative  positive
    A                      
    bar   -3.4423       NaN
    foo   -2.6277     0.857
    

    NaN 值是因为所有A == bar 行的C 都具有负值。

    如果要将这些添加到与groupby键值对应的原始帧中,即A,则需要左join

    >>> df.join(right, on='A', how='left')
         A      B       C       D  negative  positive
    0  foo    one  0.3742  0.3197   -2.6277     0.857
    1  bar    one -0.3563 -0.6296   -3.4423       NaN
    2  foo    two -0.3902 -1.3879   -2.6277     0.857
    3  bar  three -0.7834 -0.9597   -3.4423       NaN
    4  foo    two -1.2686 -0.2509   -2.6277     0.857
    5  bar    two -2.3025 -1.2960   -3.4423       NaN
    6  foo    one -0.9688  1.2477   -2.6277     0.857
    7  foo  three  0.4828  1.0047   -2.6277     0.857
    

    【讨论】:

    • 最终的df也应该按A分组。我不想按两个标准分组,我只想在您的 right 数据框中按列 A 分组。
    • @AlirezaHos 你没有意义。您需要编辑问题并显示您正在寻找的输出是什么
    • 此解决方案比其他解决方案更快!谢谢
    猜你喜欢
    • 2014-02-13
    • 2018-10-03
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    • 2013-11-07
    • 1970-01-01
    • 2018-01-06
    • 2019-03-15
    相关资源
    最近更新 更多