跳到主要内容

S2 · 分清来源,清洗数据

挑战:你拿到一份新的日志,里面混着两类东西:数据在采集和传输中出的问题,以及机器本身的状况。把数据层的问题修好,把机器层的现象原样保留,并记下你对数据做的每一处改动。

S2 的核心要求只有一条:数据层的问题要修,机器层的现象一个都不能被"修"掉。

你拿到什么​

  • 一份新的日志:30 分钟,10 Hz。
  • S1 的验收日志,作为"正常是什么样"的参照。
  • 你在 S1 写的 machine.yaml 和 check-log skill。
  • 回放页。

三条规则​

  1. 原始文件只读。 每一步处理都生成新文件。
  2. 解释不了的不删。 不确定的数据先标记,不删除、不修改。
  3. 每一处改动都记录。 写进清洗日志,格式见下文。

步骤​

1. 发现​

用 S1 的 check-log 跑新日志,得到现象记录。这一步本身就是对 S1 skill 的检验:它在一份没见过的日志上还能用吗?不能用的地方,先修 skill。

2. 分类​

S2:现象属于哪一层违反物理规律或列间关系的现象归为数据层并修复;只偏离基线的归为机器层并保留;两者都不是的标为不确定。是是否否一条现象来自 check-log违反物理规律或列间关系?数据层修复,写进清洗日志偏离验收日志的基线?机器层原样保留,留给 S4、S5不确定回放页对照,仍不确定就标注保留
判断一条现象属于哪一层。违反物理规律或列间关系的,多半是数据层;自身一致、只是偏离基线的,多半是机器层。

对每条现象,判断它属于数据层、机器层,还是暂时说不清,并写下依据:

依据倾向
违反物理规律或列间关系:球数一次跳 2、时间倒退、气缸不经中间状态直接到另一端数据层
自身一致,只是和验收日志不同:停得更久、动作更慢机器层
两种都像标为"不确定",到回放页对照;仍不确定就保留并标注

3. 修复​

只处理数据层的问题。每一类问题都有合理的处理方式,也有常见的错误做法:

问题合理的处理常见的错误
重复行时间戳和内容都相同的,只保留一行只按时间戳去重,把内容不同的行也删了
时间倒退找出跳变点,把后面整段加上偏移量删掉跳变之后的数据;或者先按时间戳去重
单位改变找出改变点,统一换算成手册的单位当作离群值删掉
数值冻结把这一段的这一列标为无效,不能恢复用前后的值插值,编出数据
缺行标出缺口,不补数据线性插值:计数会出现 3.5 这样的小数

顺序很重要。 上表前两行就是例子:时钟倒退会让一小段时间戳重复出现,但那几行的内容并不相同。先修时钟、再去重,这些行都能保住;先按时间戳去重,它们就被当作重复删掉了。示范页完整走一遍这个例子。

4. 记录​

每做一个动作,就往清洗日志里追加一行:

cleaning.jsonl(一行,为便于阅读已换行)
{"step": 2, "action": "fix_clock_jump", "rule": "time_backwards",
"rows": "5400-18006", "rows_changed": 12607, "reversible": true,
"detail": "从 08:08:59.200 这一行起,时间戳整体加 0.8 s",
"reason": "时间戳倒退 0.8 s,但各列信号连续变化,机器没有停"}

清洗日志让三件事成为可能:

  • 复现:别人,或者三个月后的你,按这份记录能从原始文件得到完全相同的结果。
  • 追溯:后面算出的任何数字,都能说清它依据的数据被改过哪些地方。
  • 审查:读这份记录就能判断每一步是否有道理,不必读你的全部代码。

清洗日志由你的代码在运行时写出,不手写,也不让 AI 代写。

5. 验证​

  • 用同一套规则重跑清洗后的文件:数据层的报警应该消失,机器层的现象应该还在。
  • 清洗前后各算一次:球数、停机次数和时长、气压均值。写下清洗改变了哪些数字、改变了多少。
  • 把清洗后的文件拖进回放页,确认不再有瞬移和跳变。

交付​

  • clean-log skill:输入原始日志和 machine.yaml,输出清洗后的文件和清洗日志。
  • 清洗后的文件、清洗日志、运行日志。
  • 一张表:每条现象的分类、依据和处理方式。
  • 清洗前后的数字对照。

验收​

  • 老师注入的每一类数据问题都被发现,并被正确处理。
  • 机器层的现象没有被删改。
  • 用你的代码重跑原始文件,得到的结果与你交的文件一致。
  • 在另一份日志上,你的 skill 不改代码就能跑通。

示范:时间倒退的处理