2017-07-19 16 views
1

私は同じ列とインデックスを持つ別のpandas DataFrame(dfIdx)の情報に基づいて合計したい情報を持つpandas DataFrame(df)を持っています。次の形式の累積合計パンダインジケータ付きデータフレーム

df = pd.DataFrame([[172770, 1442, 114581],[35464, 67062, 175285],[124399, 14294, 44104],[50608, 58802, 189253],[1000, 10000, 100000]],columns=['A','B','C']) 

とdfIdx:dfは、次の形式取る場合、特に、

dfIdx = pd.DataFrame([[0, 0, 1], [0, 0, 0], [0, 1, 0], [1, 1, 0],[0,0,1]],columns=['A','B','C']) 

を私は結果がdf前後の行を含むの行の累積和になりたいですdfIdxの値は1です。だから、結果は次のようになります。余分な信用のために

 A  B  C 
0  0  0 114581 
1  0  0  0 
2  0 82798  0 
3 383241 58802  0 
4  0  0 508642 

、私は、累積合計が拠出が含まれてどこまで戻っに関しては柔軟になりたいです。

 A  B  C 
0  0  0 114581 
1  0  0  0 
2  0 81356  0 
3 175007 58802  0 
4  0  0 289253 

は私が与えた元の例はすべて提供していませんでした実現:累積和のためのウィンドウが 1ある場合たとえば、私は結果だけを与え、多くても1つの前の行に含めたいです結果として、提案された解決策は不完全でした。私は、より多様な行動を提供するために、別の行でデータを補強しました。

+0

を使用することができます私が彼の 'df_group'を' dfIdx.loc [list(dfIdx.index)を逆にする]。cumsum()。loc [dfIdx.index、x.name] 'に変更すると、下の@ScottBostonによるようです。その他の提案はありますか? – DrTRD

答えて

2

新しい要件を満たすためにEDITと拡張データセット

df_out = (df.apply(lambda x: x.groupby(dfIdx.loc[::-1,x.name].cumsum().replace(0,pd.np.nan).bfill()) 
          .transform('cumsum') 
          .mul(dfIdx[x.name]))) 

出力:

 A  B  C 
0  0  0 114581 
1  0  0  0 
2  0 82798  0 
3 383241 58802  0 
4  0  0 508642 

余分な信用の更新:

n=1 #for summing 1 pervious value 
df_out = (df.apply(lambda x: x.groupby(dfIdx.loc[::-1,x.name].cumsum().replace(0,pd.np.nan).bfill()) 
           .rolling(n+1,min_periods=1).sum().reset_index(level=0,drop=True) 
           .mul(dfIdx[x.name]))) 

出力:

  A  B   C 
0  0.0  0.0 114581.0 
1  0.0  0.0  0.0 
2  0.0 81356.0  0.0 
3 175007.0 58802.0  0.0 
4  0.0  0.0 289253.0 

注:reversedを使用して、あなたの所見にとても近づいていました。私は同じことをやっている。そのdfIdxをグループ化する方法はすべてです。


のは、試してみましょう:

df_out = (df.apply(lambda x: x.groupby(dfIdx[x.name].cumsum().replace(0,pd.np.nan).bfill()) 
          .transform('cumsum') 
          .mul(dfIdx[x.name]))) 

出力:

n=1 #for summing 1 pervious value 
df_out = (df.apply(lambda x: x.groupby(dfIdx[x.name].cumsum().replace(0,pd.np.nan).bfill()) 
           .rolling(n+1,min_periods=1).sum().reset_index(level=0,drop=True) 
           .mul(dfIdx[x.name]))) 
 A  B  C 
0  0  0 114581 
1  0  0  0 
2  0 82798  0 
3 383241 58802  0 

とN = 1、我々は2のローリング期間を使用し、 "余分なクレジット"、のため

出力:

  A  B   C 
0  0.0  0.0 114581.0 
1  0.0  0.0  0.0 
2  0.0 81356.0  0.0 
3 175007.0 58802.0  0.0 

どのようにですか?

df_group = dfIdx.cumsum()\ 
    .replace(0,pd.np.nan)\ 
    .bfill() 

    A B C 
0 1.0 1.0 1 
1 1.0 1.0 1 
2 1.0 1.0 1 
3 1.0 2.0 1 
'変換' やDFに 'ローリング' を実行するためにグループ化

ステップ2:

ステップ1 dfIdxでグループを取得します。

df_out = df.apply(lambda x: x.groupby(df_group)        
    .rolling(n+1,min_periods=1) 
    .sum() 
    .reset_index(level=0,drop=True)) 

      A  B   C 
0 172770.0 1442.0 114581.0 
1 208234.0 68504.0 289866.0 
2 159863.0 81356.0 219389.0 
3 175007.0 58802.0 233357.0 

ステップ3レッツ・マスクやdfIdxで0に合わせ、これらの値を置き換え、我々はそれが助け場合は、解決策が提案されている複数の

df_out.mul(dfIdx)

  A  B   C 
0  0.0  0.0 114581.0 
1  0.0  0.0  0.0 
2  0.0 81356.0  0.0 
3 175007.0 58802.0  0.0