You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas GroupBy按id分组每N行统计值变化计算每分钟变化率

Pandas实现分机器统计每分钟value变化率方案

核心逻辑拆解

整个实现分4步完成,完全匹配需求的中间计算逻辑:

  • 按机器id分组,标记每条记录相对同组上一条记录的value是否发生变化,单台机器的首条作业无前置参考,不计入变化
  • 按机器id分组,为组内每条作业分配窗口编号:每3条连续作业划分为1个窗口(对应60秒时长),窗口编号从0开始递增
  • 按「机器id+窗口编号」分组,统计每个窗口内的value变化总次数,得到需求指定的中间结果表
  • 按机器id分组,用单台机器的总变化次数除以对应窗口总数,得到每分钟的平均变化率

完整可运行代码

import pandas as pd

def calc_change_rate(df):
    # 1. 标记分组内相邻记录的value变化
    df['is_change'] = df.groupby('id')['value'].diff().ne(0).astype(int)
    # 2. 分组内分配窗口编号,每3条作业一个窗口
    df['window_id'] = df.groupby('id').cumcount() // 3
    # 3. 统计每个窗口的变化次数,得到中间结果
    window_stats = df.groupby(['id', 'window_id'], as_index=False)['is_change'].sum()
    window_stats = window_stats.rename(columns={'is_change': 'changes'})
    # 4. 计算单台机器的每分钟平均变化率
    id_total = window_stats.groupby('id').agg(
        total_changes=('changes', 'sum'),
        window_cnt=('window_id', 'nunique')
    )
    id_total['rate'] = id_total['total_changes'] / id_total['window_cnt']
    final_result = id_total[['rate']].reset_index()
    return window_stats, final_result

结果验证

第一个基础示例验证

# 构造第一个示例数据
df1 = pd.DataFrame({
    "id": [1,1,1,1,2,2,2,2,2,3,3,3,3],
    "job": [1,2,3,4,1,2,3,4,5,1,2,3,4],
    "value": [42,42,42,45,38,38,40,40,42,44,44,43,43]
})
window_df1, res1 = calc_change_rate(df1)
print("=== 中间窗口统计结果 ===")
print(window_df1)
print("\n=== 最终变化率结果 ===")
print(res1)

运行输出和需求给出的预期完全一致:

=== 中间窗口统计结果 ===
   id  window_id  changes
0   1          0        0
1   1          1        1
2   2          0        1
3   2          1        1
4   3          0        1
5   3          1        0

=== 最终变化率结果 ===
   id  rate
0   1   0.5
1   2   1.0
2   3   0.5

第二个补充测试用例验证

# 构造补充测试数据
df2 = pd.DataFrame({
    "id": [1,1,1,1,1,1,2,2,2,3,3,3,3],
    "job": [1,2,3,4,5,6,1,2,3,1,2,3,4],
    "value": [0,1,2,3,4,5,0,0,0,0,1,1,2]
})
window_df2, res2 = calc_change_rate(df2)
print(res2)

运行输出完全匹配预期:

id  rate
0   1   2.5
1   2   0.0
2   3   1.0

关键避坑点

  • 计算value变化必须在id分组内调用diff(),禁止直接对全表做shift/diff,否则会把不同机器的首尾作业误判为值变化
  • 窗口编号必须使用分组内累计序号groupby('id').cumcount() // 3生成,禁止直接用全局索引整除3,否则会把不同机器的作业错误划分到同一窗口
  • 跨窗口相邻作业(上一窗口最后一条、下一窗口第一条)的值变化,会计入后一窗口的统计,和需求给出的中间结果逻辑完全对齐

内容的提问来源于stack exchange,提问作者thenewjames

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 10:48:14