带有指标DataFrame的累积和pandas DataFrame

时间:2017-07-19 13:18:51

标签: python python-3.x pandas

我有一个pandas DataFrame(df),其中包含我想根据另一个pandas DataFrame(dfIdx)中具有相同列和索引的信息求和的信息。特别是,如果df采用以下形式:

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

和以下形式的dfIdx:

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

为了获得额外的信用,我希望能够灵活地确定累积金额包括多少捐款。例如,如果累积和的窗口是1,那么我只想包含最多一个前一行,给出结果:

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

我意识到我给出的原始示例没有提供我想要的所有行为示例,因此建议的解决方案不完整。我用另一行增加了数据,以提供更多样化的行为。

1 个答案:

答案 0 :(得分:3)

编辑以满足新要求和扩展数据集

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