Pandas: 重置的计数器的滚动总和

1 投票
1 回答
45 浏览
提问于 2025-04-14 16:13

当我们从服务器收集网络流量统计数据时,这些数据会以一个不断增加的计数器形式出现,但在某个时刻会重置。假设在某个时间段内的数据点看起来是这样的:

7
15
22
29     <--- reset happens next
2
5
7
20
25     <--- reset happens again
3
7

总数应该是 (29-7) + 25 + 7 = 54。

我实际拥有的数据包括一个主机名,比如:

host1  5
host2 19
host1 7
host2 29
host1 9
host2 3

如果我把这些数据放在一个pandas的数据框中,我该如何计算滚动总和,并考虑到计数器的重置呢?

顺便提一下,这个计数器大约在10的12次方时会重置,所以我不担心重置和下一个测量点之间丢失的数据。

1 个回答

2

你可以用一个“遮罩”来找出重启的地方,把它们加起来,然后减去第一个值:

df = pd.DataFrame({'value': [7,15,22,29,2,5,7,20,25,3,7]})

out = (df.loc[df['value'].diff(-1).fillna(1).gt(0), 'value'].sum()
       -df['value'].iloc[0]
      )

输出结果:54

每组都用同样的逻辑

df = pd.DataFrame({'group': list('aaaaaabbbbb'),
                   'value': [7,15,22,29,2,5,7,20,25,3,7]})

def total(g):
    return (g[g.diff(-1).fillna(1).gt(0)].sum()
           -g.iloc[0]
          )
    
out = df.groupby('group')['value'].agg(total)

输出结果:

group
a    27
b    25
dtype: int64

详细分析:

   group  value
0      a      7   #  -7
1      a     15
2      a     22
3      a     29   # +29
4      a      2
5      a      5   #  +5 = 27

6      b      7   #  -7
7      b     20
8      b     25   # +25
9      b      3
10     b      7   #  +7 = 25

中间结果:

   group  value  diff(-1)  fillna(1)  gt(0) iloc[0]
0      a      7      -8.0       -8.0  False       X
1      a     15      -7.0       -7.0  False        
2      a     22      -7.0       -7.0  False        
3      a     29      27.0       27.0   True        
4      a      2      -3.0       -3.0  False        
5      a      5       NaN        1.0   True        
6      b      7     -13.0      -13.0  False       X
7      b     20      -5.0       -5.0  False        
8      b     25      22.0       22.0   True        
9      b      3      -4.0       -4.0  False        
10     b      7       NaN        1.0   True        

注意:g.diff(-1).fillna(1).gt(0) 也可以简化为 ~g.diff(-1).le(0)

撰写回答