首页 > 解决方案 > Pandas - 使用 GroupBy 重置的累积和

问题描述

我有几千个时间序列的数据框。


对于每个时间序列,都有一个唯一的时间戳,因此我可以强制执行顺序。


每个时间序列都有一个状态列


在有一定数量的连续 1 之前,我需要“丢弃”所有行


所以,这里有一些示例数据......

test = pd.DataFrame({
    'group': [1,1,1,1,1,1,1, 2,2,2,2,2,2,2],
    'idx':   [0,1,2,3,4,5,6, 0,1,2,3,4,5,6],
    'value': [0,1,0,1,1,1,1, 0,1,1,1,0,1,0],
})

我想要的结果是...

desired_result = pd.DataFrame({
    'group': [        1,1,1,     2,2,2,2,2],
    'idx':   [        4,5,6,     2,3,4,5,6],
    'value': [        1,1,1,     1,1,0,1,0],
})

我想我需要计算的是......

test = pd.DataFrame({
    'group': [1,1,1,1,1,1,1, 2,2,2,2,2,2,2],
    'idx':   [0,1,2,3,4,5,6, 0,1,2,3,4,5,6],
    'value': [0,1,0,1,1,1,1, 0,1,1,1,0,1,0],
   #'consec':[0,1,0,1,2,3,4, 0,1,2,3,0,1,0], -- the cumulative sum of value, but resetting whenever a 0 is encountered
   #'max_c': [0,1,1,1,2,3,4, 0,1,2,3,3,3,3], -- the cumulative max of consec
   #                  ^ ^ ^      ^ ^ ^ ^ ^   -- rows I want to keep, as max_c >= 2
})

然后我可以把行放在哪里test[ test['max_c'] >= 2 ]


但是,我该如何计算consec




编辑:我最好的尝试,但感觉非常冗长......

test['cumsum'] = test.groupby(['group'])['value'].cumsum()

test['reset'] = test['cumsum'][ test.groupby(['group'])['value'].diff() == -1 ]
test['reset'] = test['reset'].fillna(0)

test['reset_cummax'] = test.groupby(['group'])['reset'].cummax()

test['consec'] = test['cumsum'] - test['reset_cummax']

test['c_max'] = test.groupby(['group'])['consec'].cummax()

标签: pythonpandaspandas-groupby

解决方案


IIUC,您可以在列组上执行cumsuma 之后groupby,每次列值为eq0 时,您也可以创建一个新组cumsum

test['consec'] = test.groupby(['group', test['value'].eq(0).cumsum()])['value'].cumsum()
test['max_c'] = test.groupby(['group'])['consec'].cummax()
print(test)
    group  idx  value  consec  max_c
0       1    0      0       0      0
1       1    1      1       1      1
2       1    2      0       0      1
3       1    3      1       1      1
4       1    4      1       2      2
5       1    5      1       3      3
6       1    6      1       4      4
7       2    0      0       0      0
8       2    1      1       1      1
9       2    2      1       2      2
10      2    3      1       3      3
11      2    4      0       0      3
12      2    5      1       1      3
13      2    6      0       0      3

推荐阅读