使用Pandas处理DataFrame 统计传感器连续停机时段时长
Pandas识别传感器连续停机区间实现方案
核心思路是通过时间差判断连续停机段,给同一段停机的记录打统一分组标签,再分组聚合统计指标,全程不需要写复杂循环,适合新手使用。
实现步骤
- 先将时间字段转为Pandas原生datetime格式,保证时间计算准确
- 筛选出所有传感器读数为0(停机状态)的记录
- 生成分组标记:当前记录与上一条停机记录的时间差超过固定上报间隔(20分钟)时,判定为新的停机区间,分组编号累加
- 按分组聚合,取每组最早时间为停机开始时间、最晚时间为恢复结束时间
- 计算两个时间的差值,转换为分钟格式的时长字段
完整可运行代码
import pandas as pd # ---------------------- # 替换成你自己的读数据代码即可,比如pd.read_csv("你的数据文件.csv") # 这里用题目给出的样例数据做演示 raw_data = [ ["1/1/2022 9:00", 0], ["1/1/2022 9:20", 0], ["1/1/2022 9:40", 0], ["1/1/2022 10:00", 0], ["1/1/2022 10:20", 0], ["1/1/2022 10:40", 0], ["1/1/2022 12:40", 0], ["1/1/2022 13:00", 0], ["1/1/2022 13:20", 0], ["1/3/2022 1:20", 0], ["1/3/2022 1:40", 0], ["1/3/2022 2:00", 0], ["1/4/2022 14:40", 0], ["1/4/2022 15:00", 0], ["1/4/2022 15:20", 0], ["1/4/2022 17:20", 0], ["1/4/2022 17:40", 0], ["1/4/2022 18:00", 0], ["1/4/2022 18:20", 0], ["1/4/2022 18:40", 0] ] df = pd.DataFrame(raw_data, columns=["date", "Quality Sensor Reading"]) # ---------------------- # 时间格式转换 df["date"] = pd.to_datetime(df["date"]) # 筛选停机记录,按时间排序 down_records = df[df["Quality Sensor Reading"] == 0].sort_values("date").reset_index(drop=True) # 生成停机段分组标记:相邻记录时间差超过20分钟则为新分组 group_mark = (down_records["date"].diff() > pd.Timedelta(minutes=20)).cumsum() # 分组聚合统计起止时间 result = down_records.groupby(group_mark).agg( Start_Time=("date", "min"), End_Time=("date", "max") ).reset_index(drop=True) # 计算停机时长 result["Total_Down_Time"] = ( ((result["End_Time"] - result["Start_Time"]).dt.total_seconds() // 60) .astype(int) .astype(str) + " minutes" ) # 打印结果 print("Quality Sensor = 0\n") print(result)
输出结果
运行代码后得到的结果和预期完全匹配:
Quality Sensor = 0 Start_Time End_Time Total_Down_Time 0 2022-01-01 09:00:00 2022-01-01 10:40:00 100 minutes 1 2022-01-01 12:40:00 2022-01-01 13:20:00 40 minutes 2 2022-01-03 01:20:00 2022-01-03 02:00:00 40 minutes 3 2022-01-04 14:40:00 2022-01-04 15:20:00 40 minutes 4 2022-01-04 17:20:00 2022-01-04 18:40:00 80 minutes
新手注意点
- 必须先把
date列转为datetime类型,否则时间差计算会报错 - 代码逻辑兼容包含正常运行(读数非0)记录的完整数据集,不需要提前手动拆分
- 如果后续传感器上报间隔调整,只需要修改
pd.Timedelta(minutes=20)里的分钟数即可适配
内容的提问来源于stack exchange,提问作者Eliz Lim
相关产品推荐
相关产品推荐

