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

如何高效为Pandas DataFrame添加基于时间分组的Group_ID列?

高效为大型Pandas DataFrame添加分组ID列

需求描述

需要为大型Pandas DataFrame添加名为Group_ID的列,规则如下:

  • 每个Group_ID由Veh_ID和递增序号拼接而成(格式:Veh_ID_序号)
  • 同一Veh_ID下,当相邻记录的Time差值大于5000时,递增序号加1,划分新组

原始数据示例

Time    Time_slot   Veh_ID      Pwr
1       1           100         10
1       2           100         12
2       1           100         3
2       2           100         13
3       1           100         22
3       2           100         13
1       1           55          8
1       2           55          2
2       1           55          12
2       2           55          11
6000    1           100         7
6000    2           100         6
6001    1           100         11
6001    2           100         14
6001    1           55          7
6001    2           55          9
6002    1           55          9
6002    2           55          13
6003    1           55          10
6003    2           55          9

目标结果示例

Time    Time_slot   Veh_ID  Pwr Group_ID
1       1           100     10          100_1
1       2           100     12          100_1
2       1           100     3           100_1
2       2           100     13          100_1
3       1           100     22          100_1
3       2           100     13          100_1
1       1           55      8           55_1
1       2           55      2           55_1
2       1           55      12          55_1
2       2           55      11          55_1
6000    1           100     7           100_2
6000    2           100     6           100_2
6001    1           100     11          100_2
6001    2           100     14          100_2
6001    1           55      7           55_2
6001    2           55      9           55_2
6002    1           55      9           55_2
6002    2           55      13          55_2
6003    1           55      10          55_2
6003    2           55      9           55_2

当前代码问题

用户尝试用循环实现,但代码复杂且触发SettingWithCopyWarning:

df.insert(loc = 4, column = 'Group_ID',  value = 0)
for v in df.Veh_ID.unique():
    diffs = np.diff(df[df.Veh_ID == v].Time)
    change_indxs = np.where(diffs > 5000)[0] # Each location is the last of the group
    start_indx = df.index[0]
    last_indx  = df.index[-1]
    abreak     = last_indx
    for i, abreak in enumerate(change_indxs):
        aChunk = df.loc[start_indx:abreak+1]
        aChunk['Group_ID'].loc[start_indx:abreak+1] = str(v) + str(i)

错误信息:

SettingWithCopyWarning:  A value is trying to be set on a copy of a slice from a DataFrame

高效解决方案

使用Pandas的向量化操作替代循环,既避免警告又大幅提升处理大型数据的效率:

实现代码

import pandas as pd

# 1. 按Veh_ID分组,计算相邻Time的差值
df['time_diff'] = df.groupby('Veh_ID')['Time'].diff()

# 2. 标记需要分组的边界(差值>5000的位置),首行填充False
df['is_new_group'] = df['time_diff'] > 5000
df['is_new_group'] = df['is_new_group'].fillna(False)

# 3. 按Veh_ID累计分组序号,首组序号为1
df['group_num'] = df.groupby('Veh_ID')['is_new_group'].cumsum() + 1

# 4. 拼接Veh_ID和分组序号得到Group_ID
df['Group_ID'] = df['Veh_ID'].astype(str) + '_' + df['group_num'].astype(str)

# 5. 清理临时列(可选,若不需要保留中间结果)
df = df.drop(['time_diff', 'is_new_group', 'group_num'], axis=1)

代码解释

  • 步骤1:通过groupby('Veh_ID')['Time'].diff()计算每个车辆相邻记录的时间差,确保只在同一车辆内计算差值。
  • 步骤2:标记时间差大于5000的位置为新组起点,首行因为没有前序记录,填充False。
  • 步骤3:按车辆累计新组标记的数量,加1后得到每组的序号(保证从1开始)。
  • 步骤4:将车辆ID和分组序号转为字符串后拼接,得到最终的Group_ID。
  • 步骤5:删除临时列,保持DataFrame整洁。

这种方法完全避免了循环,利用Pandas的内置分组和向量化运算,处理大型数据集时效率远高于循环实现,同时不会触发SettingWithCopyWarning。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 18:06:01