2016-11-22 12 views
3

この質問には既に尋ねられている場合はお詫び申し上げますが、事前にお手数おかけしますようお願い申し上げます。この「アンピボット」データセットでパンダの部分要素と括弧の累計和

いくつかのロットで構成受注があります。各ロットは、所与ポイント値は、以下のようにしている:

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レベルで、PtsPerLotの和そのものであるPOINTS_PER_ORDERの累積和を表すCUMULATIVE_POINTS_PER_YEAR列を作成することです。したがって、指定されたロットについては、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 

私はをPtsPerLotに、またgroupby.cumsumPtsPerOrderにしようとしましたが、私が必要なものを作り出していません。

+0

PtsPerOrderの累積合計はどのくらいですか? –

+0

注文番号1234は、2つのロット間で合計12ポイントです。 – user791411

+0

PtsPerOrderの累積合計は12,24,31 ... –

答えて

1

まず、PtsPerOrderを計算します。

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 

終了:その後、各グループ内のその新しい列の最初の要素を取る

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

:各グループのあなたのデータフレームの実際の指数計算の結果に沿ってtransformに放送さを使用しますあなたが探している累積合計を計算して計算します。 NA値をスキップします。転送フレームでデータフレームを完成させる:

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

0 12.0 
1 12.0 
2 19.0 
+0

ありがとう!これはこのトリックです! – user791411

+0

*これは意味があります。 –

+0

いいえ、それは実際には@ user791411のためのものでした。私は仕様を理解することができませんでしたが、私はそれを 'パンダ'で見ると意味があります。私はたくさんの注文について混乱していました。これはあなたのことを理解していない!私はあなたの他の答えが意味をなさないとは思わなかった、それはちょうど精緻化のための示唆だった。 –

0

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 

を私はまだCumPtsPerYearのためにあなたの仕様をgrokkingないよ...

+0

あなたの助けてくれてありがとう!その例では、その順番に(列のように)12個の合計点があり、その後の順番に7個の合計点があるため、「CumPtsPerYear」は12,19となります。 – user791411

+0

@ user791411私を誤ってダウンボートしましたか? –

+0

奇妙なことに、私はあなたをアップしたばかりです! – user791411

1

まず、あなたがする必要がありますtransformation

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

次に、もう一方を作成するために、私はfiを使用しませんでした各グループの最大を見つけるためndは別の方法で、その上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