python pandas条件累积和

Gra*_*ash 9 ipython dataframe python-3.x pandas

考虑我的数据框架 df

data  data_binary  sum_data
  2       1            1
  5       0            0
  1       1            1
  4       1            2
  3       1            3
  10      0            0
  7       0            0
  3       1            1
Run Code Online (Sandbox Code Playgroud)

我想计算data_binary连续1值组内的累积和.

第一组1有一个1,sum_data只有一个1.然而,第二组1的有3分1,sum_data[1, 2, 3].

我尝试过使用np.where(df['data_binary'] == 1, df['data_binary'].cumsum(), 0)但返回

array([1, 0, 2, 3, 4, 0, 0, 5])
Run Code Online (Sandbox Code Playgroud)

这不是我想要的.

piR*_*red 14

你想取累计和data_binary并减去最近的累积和data_binary为零.

b = df.data_binary
c = b.cumsum()
c.sub(c.mask(b != 0).ffill(), fill_value=0).astype(int)

0    1
1    0
2    1
3    2
4    3
5    0
6    0
7    1
Name: data_binary, dtype: int64
Run Code Online (Sandbox Code Playgroud)

说明

让我们从并排查看每个步骤开始

cols = ['data_binary', 'cumulative_sum', 'nan_non_zero', 'forward_fill', 'final_result']
print(pd.concat([
        b, c,
        c.mask(b != 0),
        c.mask(b != 0).ffill(),
        c.sub(c.mask(b != 0).ffill(), fill_value=0).astype(int)
    ], axis=1, keys=cols))


   data_binary  cumulative_sum  nan_non_zero  forward_fill  final_result
0            1               1           NaN           NaN             1
1            0               1           1.0           1.0             0
2            1               2           NaN           1.0             1
3            1               3           NaN           1.0             2
4            1               4           NaN           1.0             3
5            0               4           4.0           4.0             0
6            0               4           4.0           4.0             0
7            1               5           NaN           4.0             1
Run Code Online (Sandbox Code Playgroud)

有问题cumulative_sum的是,其中的行data_binary是零,不复位的总和.这就是这个解决方案的动力.当data_binary零为零时,我们如何"重置"总和?简单!我将累积和切片data_binary为零,然后向前填充值.当我得到这个和累积和之间的差异时,我已经有效地重置了总和.


jez*_*ael 7

我认为你可以groupbyDataFrameGroupBy.cumsumby Series,首先将下一个值与shifted列进行比较if if equal(!=)然后再创建group by cumsum.最后更换0data_binarymask:

print (df.data_binary.ne(df.data_binary.shift()).cumsum())
0    1
1    2
2    3
3    3
4    3
5    4
6    4
7    5
Name: data_binary, dtype: int32

df['sum_data1'] = df.data_binary.groupby(df.data_binary.ne(df.data_binary.shift()).cumsum())
                                .cumsum()
df['sum_data1'] = df['sum_data1'].mask(df.data_binary == 0, 0)
print (df)
   data  data_binary  sum_data  sum_data1
0     2            1         1          1
1     5            0         0          0
2     1            1         1          1
3     4            1         2          2
4     3            1         3          3
5    10            0         0          0
6     7            0         0          0
7     3            1         1          1
Run Code Online (Sandbox Code Playgroud)