【问题标题】:Calculating sum - after rows are grouped using groupby计算总和 - 使用 groupby 对行进行分组后
【发布时间】:2020-01-01 01:13:51
【问题描述】:

我想对数据框中的特定列进行分组并计算由此创建的子组的总和,同时保留(显示)每个子组中的所有记录。

我正在尝试创建自己的信用卡费用跟踪程序。 (我知道已经有几个可用的了,但我们的想法是学习 Python。)

我有'Merchant'、'Date'、'Type'和'Amount'这些常用字段

我想做以下其中一项:

  1. 按商家分组项目,然后在每个这样的组中,将金额拆分为(两个新列)“借方”和“贷方”。我还希望能够对这些列下的金额求和。对每个商家组重复此操作。

  2. 如果无法根据交易的“类型”(即“借方”和“贷方”)进行拆分,那么我希望能够分别对借方和贷方进行求和,并且保留行项目(即显示时)。在“金额”列上执行 sum() 只会为每个商家提供一个数字,我验证它是一个不正确的金额。

我的数据框如下所示:

   Posted_Date  Amount    Type       Merchant  
0   04/20/2019  -89.70   Debit            UNI  
1   04/20/2019   -6.29   Debit          BOOKM  
2   04/20/2019  -36.42   Debit       BROOKLYN  
3   04/18/2019  -20.95   Debit  MTA*METROCARD  
4   04/15/2019  -29.90   Debit           ZARA  
5   04/15/2019   -7.70   Debit         STILES 

读入数据框并将交易标记为贷方或借方后,我拥有的代码是:

merch_new = df_new.groupby(['Merchant','Type'])
merch_new.groups

for key, values in merch_new.groups.items():
    df_new['Amount'].sum()
    print(df_new.loc[values], "\n\n")

我可以按以下方式拆分它:

    Posted_Date  Amount   Type   Merchant  
217  05/23/2019  -41.70  Debit        AT  
305  04/27/2019  -12.40  Debit        AT  



 Posted_Date  Amount    Type Merchant  
127   07/08/2019    69.25   Credit       AT  
162   06/21/2019   139.19   Credit       AT

理想情况下,我想要以下内容: the line items are displayed and a total for a given subgroup. In this case for merchant 'AT' and ideally sorted by date.

    Date    Merchant    Credit  Debit  
305 4/27/2019   AT  0   -12.4  
217 5/23/2019   AT  0   -41.7  
162 6/21/2019   AT  139.19  0  
127 7/8/2019    AT  69.25   0  

                  208.44    -54.1

看起来很简单,但我无法以这种方式对其进行格式化。

编辑: 我收到 rename_axis() 错误: rename_axis() got an unexpected keyword argument 'index' 如果我删除索引参数,'columns' 也会出现同样的错误

我搜索了很多用法(如 Benoit 所示),但找不到。他们都使用字符串或列表。我尝试使用: rename_axis(None,None) 我得到了错误: ValueError: No axis named None for object type <class 'pandas.core.frame.DataFrame'>

我不知道这是不是因为我使用的 python 版本(3.6.6)。我在 Spyder 和 Jupyter 上都试过了。但我得到同样的错误。

我用过: rename_axis(None, axis=1) 我似乎得到了想要的结果(有点) 但我无法理解这是如何解释的,因为没有指定限定符来说明它正在读取哪个参数以表示“无”。谁能解释一下?

感谢任何帮助! 非常感谢!

【问题讨论】:

  • 那么,你的问题是什么?
  • 对于您问题中包含的示例数据,您想要的输出究竟是什么?

标签: python python-3.x pandas pandas-groupby


【解决方案1】:

我认为您尝试实现这样的目标:

In [1]:
## Create example
import pandas as pd
cols = ['Posted_Date', 'Amount', 'Type', 'Merchant']  
data = [['04/20/2019', -89.70, 'Debit', 'UNI'],
        ['04/20/2019', -6.29, 'Credit', 'BOOKM'],
        ['04/20/2019', -36.42, 'Debit', 'BROOKLYN'],
        ['04/20/2019', -6.29, 'Credit', 'BOOKM'],
        ['04/20/2019', -54.52, 'Credit', 'BROOKLYN'],
        ['04/18/2019',  -20.95, 'Credit', 'BROOKLYN']]  
df = pd.DataFrame(columns=cols, data=data)

## Pivot Table with aggregation function ='sum'

df_final = pd.pivot_table(df, values='Amount', index=['Posted_Date', 'Merchant'],
               columns=['Type'], aggfunc='sum').fillna(0).reset_index().rename_axis(index=None, columns=None)

df_final['Total'] = df_final['Debit'] + df_final['Credit']

Out [1]:

    Posted_Date Merchant    Credit  Debit   Total
0   04/18/2019  BROOKLYN    -20.95  0.00    -20.95
1   04/20/2019  BOOKM       -12.58  0.00    -12.58
2   04/20/2019  BROOKLYN    -54.52  -36.42  -90.94
3   04/20/2019  UNI         0.00    -89.70  -89.70

​

【讨论】:

  • 谢谢你,伯努瓦。我也可以使用您的解决方案。我只是编辑了问题以澄清。有没有办法以这种方式获得结果?
  • 另外,在 Benoit 的解决方案中,如果我想添加另一个标题为“Total”的列,这将是借方和贷方列的总和,我该怎么做?
  • 我刚刚编辑了我的答案,您正在寻找这样的东西吗?
  • 谢谢你,Benoit;我看到您清理了它的显示方式并将发布日期添加到结果中。我尝试了同样的方法,但我得到了“Posted_Date”的 KeyError。我尝试将它添加到 df_final(您在使用数据透视表功能之前创建的):df_final = df_new[['Posted Date','Merchant', 'Type', 'Amount']].groupby(by=['Merchant', 'Type']).sum().reset_index() 但我仍然遇到同样的错误......有什么建议吗?
  • 这个错误意味着您的数据框中没有名为 posted_Date 的列。不就是叫Date吗?只需使用数据框的真实列编辑此代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
  • 2017-05-31
  • 2018-03-12
  • 2021-07-14
  • 2016-07-18
相关资源
最近更新 更多