如何一次对两个不同的列求和,其中一个包含熊猫中的十进制对象?



>我有一个数据帧,我想聚合两个不同列的总和。这是我原始数据帧的df.head(5)

price           name  quantity transaction_amount
pk                                                  
48  1.00      Product 1         1               1.00
48  1.00      Product 1         4               4.00
63  1.00      Product 2         2               2.00
63  1.00      Product 2         3               3.00
63  1.00      Product 2         1               1.00

我想按pk对它们进行分组,这是产品的数据库主键,并获取transaction_amount列和quantity金额列的总和。但是当我这样做df.groupby(['pk', 'name']).sum()时,我得到这个:

quantity
pk name                           
48 Product 1                   543
63 Product 2                 17234
38 Product 3                  4014
39 Product 4                 11053
40 Product 5                 13406

transaction_amount列在哪里?transaction_amount是事务中的quantity和该项在该事务中的price。如果应用了折扣或其他什么,这可能会在每笔交易中发生变化。我们需要记录购买时为商品收取的费用。因此,我期望的结果将具有quantity(总量(,transaction_amounts(总量(,name,以及如下所示的pk

quantity  transaction_amount
pk name                           
48 Product 1                   543              543.00
63 Product 2                 17234           89,000.93
38 Product 3                  4014            2,000.32
39 Product 4                 11053           25,000.36
40 Product 5                 13406            6,000.12

我阅读了.sum()的文档,但没有一个选项适合我。如果我删除price列并运行.sum(level=0)则需要很长时间。看看这两种不同方法的时间(更快的方法只对quantity列求和(。

In [237]: %%timeit
...: df.groupby(['pk', 'name']).sum(level=0)
...: 
1 loop, best of 3: 3.04 s per loop
In [239]: %%timeit
...: df.groupby(['pk', 'name']).sum()
...: 
...: 
10 loops, best of 3: 42.4 ms per loop

.sum(axis=1)的结果也相似。

当我跑步时

df.groupby(['pk', 'name']).sum()

我得到

price  quantity  transaction_amount
pk name                                          
48 Product 1    2.0         5                 5.0
63 Product 2    3.0         6                 6.0

这向我表明你的pricetransaction_amount是对象。

由于您使用的是decimal.Decimal对象,因此numpy.sum不会处理您的对象。因此,只需遵循内置sum

In [18]: df
Out[18]:
pk price       name  quantity transaction_amount
0  48   1.0  Product 1         1                1.0
1  48   1.0  Product 1         4                4.0
2  63   1.0  Product 2         2                2.0
3  63   1.0  Product 2         3                3.0
4  63   1.0  Product 2         1                1.0
In [19]: df.groupby(['pk', 'name']).aggregate({
...:     "quantity":np.sum,
...:     "price":sum,
...:     "transaction_amount":sum
...: })
Out[19]:
price  quantity transaction_amount
pk name
48 Product 1   2.0         5                5.0
63 Product 2   3.0         6                6.0

请注意,这会很慢,但这是使用 dtype 列object必须付出的代价。

您可以像这样指定要求和的列。

df.groupby(['pk','name'])['quantity','transaction_amount'].sum()

最新更新