2017-07-19 126 views
1

我有一個熊貓數據框(df)與我想基於另一個熊貓DataFrame(dfIdx)中的信息相加的信息與相同的列和索引。特別是,如果df的形式如下:累積和熊貓DataFrame與指標DataFrame

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']) 

我想要的結果是行的累積和的行之前和包括在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 

對於額外的信用,我想就能夠靈活地累積和如何追溯到包括貢獻。例如,如果累積和窗口爲1,然後我只希望在一個最上一行包括,賦予結果:

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

我意識到我給原來的例子並沒有提供所有的我想要的行爲例子,因此,建議的解決方案是不完整的。我用另一行增加了數據以提供更多不同的行爲。

+0

如果有幫助,提出的解決方案如果我將'df_group'修改爲'dfIdx.loc [list(reversed(dfIdx.index))]。cumsum()。loc [dfIdx.index,x.name]'',下面的@ScottBoston似乎可以工作。還有其他建議嗎? – DrTRD

回答

2

編輯以滿足新的需求和擴大數據集

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]))) 

輸出:

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

而對於 「加分」,其中n = 1,我們使用的2滾動週期:

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  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 

如何?

第1步得到的分組中dfIdx:

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 

第2步使用分組做 '變換' 或DF '滾動'。

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