如何使用另一列中的标记停止和重新启动 cumsum

How to stop and restart cumsum using a marker in another column

我有一个 pandas 数据框,其中的值需要在每个设备的一个周期内求和,但周期结束标记在另一列(一个易于识别的事件行)中。 cumsum 必须一直运行直到它找到这个周期结束标记,然后从零(下一行的第一个值)重新开始。

  device_name value end
0   A5         1    False
1   A5         7    False
2   A5         2    True
3   A5         1    False
4   A5         1    False
5   A5         1    False
6   A5         1    True
7   A6         2    False
8   A6         4    False
9   A6         2    False
10  A6         2    True
11  A6         2    False
12  A6         2    False

结果应该是这样的

  device_name value end     total
0   A5         1    False    1  
1   A5         7    False    8
2   A5         2    True     10
3   A5         1    False    1
4   A5         1    False    2
5   A5         1    False    3
6   A5         1    True     4
7   A6         2    False    2
8   A6         4    False    6
9   A6         2    False    8
10  A6         2    True     10
11  A6         2    False    2
12  A6         2    False    4

我尝试了 cumsum 但我无法将一个句点的结尾与另一个句点分开,我可以遍历行,如果我在 df.end.shift(1) 上找到 True,我会忽略最后一个值,但是至少有 60000 并且可能有更快的方法,有什么建议吗?

IIUC,您希望每组 cumsum,直到达到 True。然后,这一行之后,重新开始计数。

您可以使用基于“结束”值的额外组(也使用 cumsum):

df['total'] = (df.groupby(['device_name',
                           df['end'].shift(1, fill_value=0).cumsum()])
               ['value'].cumsum())

输出:

   device_name  value    end  total
0           A5      1  False      1
1           A5      7  False      8
2           A5      2   True     10
3           A5      1  False      1
4           A5      1  False      2
5           A5      1  False      3
6           A5      1   True      4
7           A6      2  False      2
8           A6      4  False      6
9           A6      2  False      8
10          A6      2   True     10
11          A6      2  False      2
12          A6      2  False      4

注意。请注意,我为第 2 行

得到了不同的值

注意事项2。对于纯粹主义者,额外的组也可以使用 groupby 来计算。在这种情况下,这并不重要。内部组不会在第一个组之后从零开始,但它们的名称不会在输出中的任何地方使用。

cnt = 0
def fetch_flag_col(x):
    global cnt
    resp = cnt
    if(x): cnt+=1
    return resp

df["flag"] = df["end"].apply(fetch_flag_col)
df["total"] = df.groupby(["device_name ","flag"])["Value"].cumsum()

我不确定使用本机 pandas api 是否有直接的功能或复杂的方法来执行此操作,但使用上述方法可以在 O 中实现所需的结果(n) 时间复杂度。

我们正在做的是,创建一个名为 flag 的中间列,这将有助于 .cumsum(),方法决定行的范围,它必须进行累积。