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

Python 如果一个列中包含十进制对象,如何一次对两个不同的列求和?,python,pandas,Python,Pandas,我有一个数据框,我想为两个不同的列聚合总和。这是我的原始数据帧的df.head(5) price name quantity transaction_amount pk 48 1.00 Product 1 1 1.00 48 1.00 Product 1 4

我有一个数据框,我想为两个不同的列聚合总和。这是我的原始数据帧的
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\u amount
列和
quantity
amount列的总和。但是当我执行
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
交易金额列在哪里<代码>交易金额
是交易中该项目的
数量
,以及该交易中该项目的
价格
。如果应用了折扣或其他方式,则每笔交易都可能发生变化。我们需要记录购买时该物品的费用。因此,我期望的结果将有
数量
(总数量),
交易金额
(总金额),
名称
,和
主键
,如下所示:

                          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
我读了这本书,但没有一个选项对我有效。如果我删除
price
列并运行
.sum(level=0)
需要很长时间。看看这两种不同方法的时间(较快的方法只对
数量
列求和)

运行时,
.sum(axis=1)
的结果也类似。

df.groupby(['pk', 'name']).sum()
我明白了


这向我表明您的
价格
交易金额
是对象。

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

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

由于您使用的是
decimal.decimal
对象,因此
numpy.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

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

检查
dtypes
…我刚刚发布了该类型以响应piRSquared。他们是小数,他们是小数
In[251]:type(df.transaction\u amount.iloc[0])Out[251]:decimal.decimal
@CoryMadden Ok,这意味着您的列是
dtype=object
。您使用的是
decimal.decimal
,因为您需要精度吗?@juanpa.arrivillaga是的,是钱。“当我用其他方式来称呼它时,我能够得到正确的结果,但我想用一种更简单的方式来做它。”科里马登好吧,我希望你马上意识到你的效率会被搞砸。但是,基本上,
numpy
矢量化的
.sum
不会处理
decimal.decimal
对象。编写您自己的
\u sum
函数,见鬼,甚至内置的
sum
也可以。哈!是交易金额栏让它变得如此缓慢。我真不敢相信我没有联系上。嗯,我想我已经在我的帖子里找到了解决问题的方法……我也试过了,但它给了我同样的结果。谢谢,这确实是问题所在。我根本没有连接到十进制类型。@CoryMadden
pandas
/
numpy
是围绕基本数组构建的,具有固定大小的数字类型。虽然它可以处理
对象
,但不要指望内置例程发挥得很好。绝对不要期望它会很快。尽管如此,至少您保持了编写pandas代码的相对表达性和易用性。我认为numpy对财务数据很好,因此保留了小数点。我可以把它当作一个浮点数,但它失去了它的准确性。据我所知,
sum
np.sum
'sum'
被同等对待。使这项工作正常的原因是,您明确表示希望获取该列的总和,而groupby.sum不包括对象数据类型的列
df.groupby(['pk','name']).sum(numeric_only=False)
在这种情况下也可以使用。@ayhan很高兴我回头看了这个问题。所以没有提醒我。这完美地修复了它。因为我认为小数是“数字”,所以我没有试着这样做。
df.groupby(['pk','name'])['quantity','transaction_amount'].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