| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- """生成整机多缸振动事件标签、验证表和摘要。"""
- from __future__ import annotations
- import json
- import sys
- from pathlib import Path
- import pandas as pd
- ROOT = Path(__file__).resolve().parents[1]
- if str(ROOT) not in sys.path:
- sys.path.insert(0, str(ROOT))
- from _tmp_cylinder_vibration import config, machine_event_html, machine_events, unified_labels
- def main() -> None:
- frame = pd.read_csv(config.OUTPUT_DIR / "vibration_features_full_local.csv")
- frame["sample_time"] = pd.to_datetime(frame["sample_time"])
- labels = pd.read_csv(config.OUTPUT_DIR / "cylinder_vibration_label_unified.csv")
- hourly = pd.read_csv(config.OUTPUT_DIR / "vibration_hourly_labels.csv")
- hourly["start_hour"] = pd.to_datetime(hourly["start_hour"])
- runs = machine_events.build_runs(frame)
- events, candidates, windows = machine_events.build_machine_events(labels, frame, hourly, runs)
- validation = machine_events.validate_events(events)
- summary = machine_events.build_summary(events, candidates, validation, runs)
- events.to_csv(
- config.OUTPUT_DIR / "machine_vibration_events.csv",
- index=False,
- date_format="%Y-%m-%d %H:%M:%S",
- )
- candidates.to_csv(
- config.OUTPUT_DIR / "machine_event_candidates.csv",
- index=False,
- date_format="%Y-%m-%d %H:%M:%S",
- )
- validation.to_csv(
- config.OUTPUT_DIR / "machine_event_validation.csv",
- index=False,
- date_format="%Y-%m-%d %H:%M:%S",
- )
- (config.OUTPUT_DIR / "machine_event_summary.json").write_text(
- json.dumps(summary, ensure_ascii=False, indent=2, default=str),
- encoding="utf-8",
- )
- temperature = unified_labels._map_external(
- Path("/Users/zhouhao/Code/Python/Compressor/_tmp_temperature/out/温度异常段.csv"),
- "温度异常",
- "T",
- unit="5号机",
- )
- machine = events.reindex(columns=unified_labels.CORE_FIELDS)
- combined = pd.concat([temperature, machine], ignore_index=True)
- combined.to_csv(
- config.OUTPUT_DIR / "fault_label_unified_machine_preview.csv",
- index=False,
- date_format="%Y-%m-%d %H:%M:%S",
- )
- lines = [
- "# 5 号机缸体振动整机事件标签",
- "",
- "## 规则",
- "",
- "- 稳定运行段:开机后 6 小时、停机前 6 小时不生成最终事件;",
- "- 不排除首次基线预热段;4 月以前只是未取得数据;",
- "- 24 小时窗口内至少 4 个不同缸出现候选标签;",
- "- 其中至少 2 条达到“异常”或“严重异常”;",
- "- 相邻候选窗口合并为一个整机事件;",
- "- 事件不指定故障缸,故障缸只用于事后验证。",
- "",
- "## 结果",
- "",
- f"- 候选标签:{len(candidates)} 条;",
- f"- 整机事件:{len(events)} 个;",
- f"- 运行段:{len(runs)} 个;",
- f"- 有事件运行段:{summary['event_runs']} 个;",
- f"- 无事件运行段:{summary['normal_runs']} 个;",
- f"- 验证事件:{summary['validation']['hit']}/{summary['validation']['total']} 命中。",
- "",
- "## 事件列表",
- "",
- ]
- lines.append("| 标签ID | 开始 | 结束 | 等级 | 参与缸 | 异常缸 | 严重异常缸 | 验证提前量 |")
- lines.append("|---|---|---|---|---|---:|---:|---:|")
- lead_map = {
- row.machine_label_id: row.lead_days
- for row in validation.itertuples(index=False)
- if row.hit
- }
- for row in events.itertuples(index=False):
- lead = lead_map.get(row.标签ID)
- lines.append(
- f"| {row.标签ID} | {row.开始小时} | {row.结束小时} | {row.阶段} | "
- f"{row.参与缸} | {row.异常缸数} | {row.严重异常缸数} | "
- f"{'—' if lead is None else f'{lead:.2f} 天'} |"
- )
- lines.extend([
- "",
- "## 验证",
- "",
- "| 事件 | 故障缸 | 命中 | 整机事件 | 开始 | 结束 | 提前量 |",
- "|---|---|---|---|---|---|---:|",
- ])
- for row in validation.itertuples(index=False):
- lines.append(
- f"| {row.event_id} | {row.fault_cylinder} | {'是' if row.hit else '否'} | "
- f"{row.machine_label_id} | {row.start_time} | {row.end_time} | "
- f"{'—' if not row.hit else f'{row.lead_days:.2f} 天'} |"
- )
- (config.OUTPUT_DIR / "machine_event_labels.md").write_text("\n".join(lines) + "\n", encoding="utf-8")
- machine_event_html.export_machine_events(frame, events, candidates, validation)
- print(f"[machine] candidates={len(candidates)}, events={len(events)}, runs={len(runs)}, event_runs={summary['event_runs']}, preview={len(combined)}")
- print(f"[machine] validation={summary['validation']['hit']}/{summary['validation']['total']}")
- print(events[["标签ID", "开始小时", "结束小时", "阶段", "参与缸", "异常缸数", "严重异常缸数"]].to_string(index=False))
- if __name__ == "__main__":
- main()
|