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

Pandas按连续相同Geofence分组 提取每组首入末出时间

问题背景

Python实现Geofence停留段统计时,直接按Geofence字段分组会将所有同名围栏合并,无法识别被其他围栏间隔开的独立停留段。
现有DataFrame包含Geofence、Time_in、Time_out、Total_time四个字段,样例数据如下:

Geofence              Time_in             Time_out Total_time
0      30TA  2022-07-12 20:34:07  2022-07-12 20:44:36    0:10:29
1       KNS  2022-07-12 20:47:08  2022-07-12 20:51:39    0:04:31
2       KNS  2022-07-12 20:52:09  2022-07-12 20:54:37    0:02:28
3       KNS  2022-07-12 21:04:38  2022-07-12 21:24:40    0:20:02
4      30TA  2022-07-12 21:27:13  2022-07-12 21:33:13    0:06:00
5       KNS  2022-07-12 21:37:14  2022-07-12 22:00:16    0:23:02
6      30TA  2022-07-12 22:02:44  2022-07-12 22:19:48    0:17:04
7       KNS  2022-07-12 22:22:19  2022-07-12 22:44:49    0:22:30
8      30TA  2022-07-12 22:46:49  2022-07-12 22:48:49    0:02:00
9      30TA  2022-07-12 22:50:22  2022-07-12 22:55:52    0:05:30
10     30TA  2022-07-12 22:56:23  2022-07-12 23:11:24    0:15:01
11      KNS  2022-07-12 23:13:54  2022-07-12 23:39:27    0:25:33
12     30TA  2022-07-12 23:41:27  2022-07-12 23:47:27    0:06:00

需求规则

  • 按连续相同的Geofence值划分停留组:例如索引1-3行连续为KNS属于同一组,后续出现的KNS如果中间间隔了30TA记录,则单独划分为新组
  • 每个分组提取3个字段:
    • Geofence围栏名称
    • 组内第一条记录的Time_in(进入围栏时间)
    • 组内最后一条记录的Time_out(离开围栏时间)
  • 最终输出仅包含Geofence、Time_in、Time_out三列的汇总DataFrame

原有错误实现

直接使用groupby(['Geofence'])会合并所有同名围栏,无法区分间断出现的独立停留段,代码如下:

import pandas as pd
df = pd.read_excel(r'KNS_Night_Shift_GPS_Report_2022-07-15.xlsx', engine='openpyxl')
df = df.loc[df['Grouping'] == 'XE3257X', ['Geofence', 'Time in', 'Time out']]

for i, g in df.groupby(['Geofence']):
    print(g)
实现方案

核心思路是先为每一段连续相同的Geofence生成唯一分组ID,再基于该ID做聚合,避免合并非连续的同名围栏。

完整代码

import pandas as pd

# 原有数据读取逻辑保持不变
df = pd.read_excel(r'KNS_Night_Shift_GPS_Report_2022-07-15.xlsx', engine='openpyxl')
df = df.loc[df['Grouping'] == 'XE3257X', ['Geofence', 'Time in', 'Time out']]

# 关键步骤:生成连续段分组ID
# 当当前行Geofence和上一行不一致时,分组序号+1,相同则保持同组
df['stay_group_id'] = (df['Geofence'] != df['Geofence'].shift()).cumsum()

# 按分组ID聚合,提取需要的字段
result = df.groupby('stay_group_id', as_index=False).agg(
    Geofence=('Geofence', 'first'),
    Time_in=('Time in', 'first'),
    Time_out=('Time out', 'last')
)

print(result)

输出结果

基于提供的样例数据,运行后输出如下:

Geofence              Time_in             Time_out
0     30TA  2022-07-12 20:34:07  2022-07-12 20:44:36
1      KNS  2022-07-12 20:47:08  2022-07-12 21:24:40
2     30TA  2022-07-12 21:27:13  2022-07-12 21:33:13
3      KNS  2022-07-12 21:37:14  2022-07-12 22:00:16
4     30TA  2022-07-12 22:02:44  2022-07-12 22:19:48
5      KNS  2022-07-12 22:22:19  2022-07-12 22:44:49
6     30TA  2022-07-12 22:46:49  2022-07-12 23:11:24
7      KNS  2022-07-12 23:13:54  2022-07-12 23:39:27
8     30TA  2022-07-12 23:41:27  2022-07-12 23:47:27

逻辑说明

  • df['Geofence'].shift():将Geofence列向下错位1行,用于对比当前行和上一行的围栏值
  • !=判断:当前后两行围栏值不同时返回True(等价于数值1),相同时返回False(等价于数值0)
  • cumsum():对布尔值做累加,每遇到一次围栏变化,序号就加1,自然为每一段连续相同的围栏分配了唯一ID

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:15:58