3. 生鲜冷链运输温度曲线分段与超温事件提取

任务对象与数据形态

冷藏车温度记录通常来自车厢内1~2个温度探头,采样间隔常见为1分钟或5分钟,字段至少包含时间戳与温度值。全程可划分为三个业务阶段:装货阶段(开门装货,温度易波动)、运输阶段(车门关闭,温度应稳定在设定区间)、卸货阶段(开门卸货,温度再次波动)。超温事件指温度连续超出允许上限(如8℃)并持续超过最短判定时长(如5分钟)的片段,需要提取起止时间、持续时长与峰值温度。

本案例采用“阶段切分 + 阈值判定 + 事件合并”的处理链:先用时间间隔与温度突变识别阶段边界,再在运输阶段内做超温判定,最后把相邻超温点合并为事件并统计指标。下图给出处理链与关键判据。

原始温度记录(示意) ℃ 时间 上限8℃ 超温段 装货阶段 运输阶段(稳定区间) 卸货 处理链与关键判据 ① 阶段切分 判据:相邻记录时间差 Δt > 15min 视为阶段断点 结合温度突变幅度辅助确认 ② 超温点标记 条件:温度 > 8℃ 仅在运输阶段内判定 输出布尔标记列 ③ 事件合并 连续超温点合并为事件 间隔≤2个采样点视为同一事件 持续时长≥5min 才保留 ④ 指标提取 起止时间、持续时长 峰值温度、峰值时刻 所属阶段 输出事件清单(示例结构) 事件编号 开始时间 结束时间 持续时长(min) 峰值温度(℃) 所属阶段 判定 E01 08:12 08:19 7 9.4 装货 超温 E02 10:35 10:42 7 8.7 运输 超温 E03 14:50 14:53 3 8.2 卸货 短时波动,剔除

实现步骤与关键代码

下面用 Python + pandas 完成整个流程。示例数据为构造的教学数据,用于演示判据与输出结构,不代表真实车辆实测结果。

import pandas as pd
import numpy as np

# 1. 构造教学示例数据:1分钟采样,含装货/运输/卸货三段
np.random.seed(42)
t1 = pd.date_range("2024-06-01 08:00", "2024-06-01 08:30", freq="1min")
t2 = pd.date_range("2024-06-01 08:45", "2024-06-01 14:30", freq="1min")
t3 = pd.date_range("2024-06-01 14:45", "2024-06-01 15:10", freq="1min")
temp1 = np.random.normal(7.5, 1.2, len(t1))
temp2 = np.random.normal(4.0, 0.4, len(t2))
temp3 = np.random.normal(7.0, 1.0, len(t3))
# 人为注入两段超温
temp1[12:19] = [8.5, 9.0, 9.4, 9.1, 8.8, 8.6, 8.3]
temp2[110:117] = [8.2, 8.5, 8.7, 8.6, 8.4, 8.3, 8.1]
df = pd.DataFrame({
    "ts": np.concatenate([t1, t2, t3]),
    "temp": np.concatenate([temp1, temp2, temp3])
}).sort_values("ts").reset_index(drop=True)

# 2. 阶段切分:时间差 > 15min 视为断点
df["gap_min"] = df["ts"].diff().dt.total_seconds().div(60).fillna(0)
df["seg_id"] = (df["gap_min"] > 15).cumsum()
seg_map = {0: "装货", 1: "运输", 2: "卸货"}
df["stage"] = df["seg_id"].map(seg_map)

# 3. 超温点标记(仅运输阶段判定,也可按业务扩展到全部阶段)
UPPER = 8.0
df["over"] = (df["temp"] > UPPER) & (df["stage"] == "运输")

# 4. 事件合并:连续超温点归为同一事件
df["event_flag"] = (df["over"] != df["over"].shift()).cumsum()
events = []
for _, g in df[df["over"]].groupby("event_flag"):
    dur = (g["ts"].max() - g["ts"].min()).total_seconds() / 60
    if dur < 5:          # 持续时长不足5分钟,剔除
        continue
    peak_idx = g["temp"].idxmax()
    events.append({
        "开始时间": g["ts"].min(),
        "结束时间": g["ts"].max(),
        "持续时长(min)": round(dur, 1),
        "峰值温度(℃)": round(g["temp"].max(), 2),
        "峰值时刻": g.loc[peak_idx, "ts"],
        "所属阶段": g["stage"].iloc[0]
    })
event_df = pd.DataFrame(events).reset_index(drop=True)
event_df.insert(0, "事件编号", [f"E{i+1:02d}" for i in range(len(event_df))])
print(event_df)

结果判读与验证

  • 阶段切分验证:检查每个 seg_id 的时间跨度是否与装货、运输、卸货的实际作业时间吻合;若某段被误切,优先排查采样中断或时间戳跳变。
  • 事件完整性:对照原始曲线,确认每个温度尖峰都被归入某个事件,且没有把同一段超温拆成两个事件(检查合并间隔参数)。
  • 短时波动剔除:持续时长小于5分钟的片段(如卸货开门瞬间)应被剔除,避免误报;若业务要求更严格,可把最短时长调至10分钟。
  • 峰值定位:峰值温度应等于该事件内温度最大值,峰值时刻应与原始记录一致,可用于后续追溯。
若温度探头存在漂移,建议在超温判定前先做基线校正(如用运输阶段前30分钟均值作为参考),避免系统性偏差导致误报或漏报。