大熊猫与groupby的部分元素累计总数

大熊猫与groupby的部分元素累计总数

问题描述:

如果此问题已被询问,但道歉,但事先感谢您的帮助。大熊猫与groupby的部分元素累计总数

在这个“未转义的”数据集中,有订单由几个组成。每个地块具有给定的值,如下:

CustID  Date   OrderNum LotNum PtsPerLot 
A123  1/1/2015  1234  A  2    
A123  1/1/2015  1234  B  10 
A123  1/1/2015  5678  A  7 

我的目标是在每一个Lot级别创建CUMULATIVE_POINTS_PER_YEAR柱表示的POINTS_PER_ORDER累积总和,它本身的PtsPerLot的总和。因此,对于给定的批次,CumPtsPerYear将显示给定年份中帐户的所有POINTS_PER_ORDER的累计总数。

CustID  Date   OrderNum LotNum PtsPerLot *PtsPerOrder* *CumPtsPerYear* 
A123  1/1/2015  1234  A  2   12    12 
A123  1/1/2015  1234  B  10   12    12 
A123  1/1/2015  5678  A  7   7    19 

任何想法?我试过上的groupby.cumsumPtsPerOrder上的另一个groupby.cumsum,但它没有产生我所需要的。

+0

CumPtsPerYear是PtsPerOrder的累积和? –

+0

这两个地段之间的订单#1234总计12点。 – user791411

+0

正确,但PtsPerOrder的累计总和为12,24,31 ... –

首先,计算PtsPerOrder。使用transform广播沿着你的数据框的实际指数各组中的计算结果:

df['PtsPerOrder'] = df.groupby('OrderNum')['PtsPerLot'].transform(sum) 

然后取各组中的新列的第一个元素:

df['CumPtsPerYear'] = df.groupby('OrderNum')['PtsPerOrder'].head(1) 

df 
Out[27]: 
    CustID  Date OrderNum LotNum PtsPerLot PtsPerOrder CumPtsPerYear 
0 A123 1/1/2015  1234  A   2   12   12.0 
1 A123 1/1/2015  1234  B   10   12   NaN 
2 A123 1/1/2015  5678  A   7   7   7.0 

结束通过执行您正在搜索的累计总和进行计算。它会跳过NA值。您使用正向填充完成数据框:

df['CumPtsPerYear'].cumsum().ffill() 

0 12.0 
1 12.0 
2 19.0 
+0

谢谢!这是这个技巧! – user791411

+0

*这个*有道理。 –

+0

不,这实际上是为了@ user791411。我无法理解规范,但是当我在“熊猫”中看到它时,它现在是有道理的。我对许多和ordernums感到困惑。没意识到这是你!我认为你的其他答案没有意义,这只是一个阐述。 –

要获得问题的第一部分PtsPerOrder,您需要一个变换sum是一个聚合。因此,使用.transform

In [10]: df 
Out[10]: 
      Date OrderNum LotNum PtsPerLot 
CustID 
A123 1/1/2015  1234  A   2 
A123 1/1/2015  1234  B   10 
A123 1/1/2015  5678  A   7 

In [11]: df.groupby('OrderNum')['PtsPerLot'].transform('sum') 
Out[11]: 
CustID 
A123 12 
A123 12 
A123  7 
dtype: int64 

并用它来创建新列...

In [13]: df['PtsPerOrder'] = df.groupby('OrderNum')['PtsPerLot'].transform('sum') 

In [14]: df 
Out[14]: 
      Date OrderNum LotNum PtsPerLot PtsPerOrder 
CustID 
A123 1/1/2015  1234  A   2   12 
A123 1/1/2015  1234  B   10   12 
A123 1/1/2015  5678  A   7   7 

我还没有所著的Grokking您的CumPtsPerYear规范...

+0

感谢您的帮助!在这种情况下,因为按照该顺序(如列中)总共有12个点,并且在随后的顺序中总共有7个点,“CumPtsPerYear”将是12,19。 – user791411

+0

@ user791411是否意外地使我失望了? –

+0

奇怪的是,但我只是upvoted你! – user791411

首先,你需要使用transformation

df['*PtsPerOrder*'] = df.groupby('OrderNum')['PtsPerLot'].transform(sum) 

然后为了创建另一个,我没有fi第二另一种方式,要找到每个组的最大,做一个cumsum和合并,早在:不出所料

weird_cumsum = df.groupby('OrderNum')['*PtsPerOrder*'].max().cumsum().to_frame() 
weird_cumsum.columns = ['*CumPtsPerYear*'] 
weird_cumsum 

      *CumPtsPerYear* 
OrderNum     
1234     12 
5678     19 

df.merge(weird_cumsum, left_on='OrderNum', right_index=True, how='left') 

结果:

CustID  Date OrderNum LotNum PtsPerLot *PtsPerOrder* *CumPtsPerYear* 
0 A123 2015-01-01  1234  A   2    12    12 
1 A123 2015-01-01  1234  B   10    12    12 
2 A123 2015-01-01  5678  A   7    7    19