run_intervals.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. """第二轮:单点候选 -> 连续时间段 + 多缸实际曲线。
  2. 用法:
  3. python3 _tmp_cylinder_vibration/run_intervals.py
  4. """
  5. from __future__ import annotations
  6. import json
  7. import sys
  8. from pathlib import Path
  9. import pandas as pd
  10. ROOT = Path(__file__).resolve().parents[1]
  11. if str(ROOT) not in sys.path:
  12. sys.path.insert(0, str(ROOT))
  13. from _tmp_cylinder_vibration import config, data, intervals, labels, plots_actual
  14. def main() -> None:
  15. features_path = config.OUTPUT_DIR / "vibration_features_refined.csv"
  16. points_path = config.OUTPUT_DIR / "vibration_labels_refined.csv"
  17. baseline_path = config.OUTPUT_DIR / "baseline.json"
  18. if not features_path.exists() or not points_path.exists() or not baseline_path.exists():
  19. raise SystemExit("请先运行 run.py --stage all")
  20. frame = labels.prepare_frame(pd.read_csv(features_path).to_dict("records"), 15)
  21. baseline = json.loads(baseline_path.read_text(encoding="utf-8"))
  22. frame, _, _ = labels.build_labels(frame, 15, baseline=baseline)
  23. point_labels = pd.read_csv(points_path)
  24. for column in ("start_time", "end_time", "max_time"):
  25. if column in point_labels:
  26. point_labels[column] = pd.to_datetime(point_labels[column], errors="coerce")
  27. result = intervals.build_intervals(frame, point_labels)
  28. result_path = config.OUTPUT_DIR / "vibration_intervals_refined.csv"
  29. result.to_csv(result_path, index=False, date_format="%Y-%m-%d %H:%M:%S")
  30. print(f"[intervals] {len(result)} -> {result_path}")
  31. temperature = data.load_temperature_reference()
  32. validation = intervals.validate_events(result, temperature)
  33. validation_path = config.OUTPUT_DIR / "event_validation_intervals.csv"
  34. validation.to_csv(validation_path, index=False, date_format="%Y-%m-%d %H:%M:%S")
  35. for event in config.EVENTS:
  36. plots_actual.plot_feature_grid(frame, result, baseline, event)
  37. plots_actual.plot_waveform_grid(frame, result, event)
  38. summary = {
  39. "point_labels": len(point_labels),
  40. "intervals": len(result),
  41. "event_hits": int(validation["vibration_hit"].sum()),
  42. "false_alarm_intervals": int(validation.attrs.get("false_alarm_intervals", 0)),
  43. "false_alarm_hours": float(validation.attrs.get("false_alarm_hours", 0.0)),
  44. "event_validation": validation.to_dict("records"),
  45. }
  46. summary_path = config.OUTPUT_DIR / "interval_summary.json"
  47. summary_path.write_text(json.dumps(summary, ensure_ascii=False, indent=2, default=str), encoding="utf-8")
  48. print(json.dumps(summary, ensure_ascii=False, indent=2, default=str))
  49. print(f"output: {config.OUTPUT_DIR}")
  50. if __name__ == "__main__":
  51. main()