spring_compare.py 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. """Daily-weighted spring state comparison, not a test of seasonal causality."""
  2. import csv
  3. from collections import defaultdict
  4. from pathlib import Path
  5. import numpy as np
  6. def main():
  7. root = Path("cache/indicator")
  8. output = []
  9. for unit in ("7", "8", "9"):
  10. filename = f"高密度特征_{unit}号_2026.csv" if unit != "9" else "高密度特征_9号_2026春季.csv"
  11. with (root / filename).open(encoding="utf-8-sig") as handle:
  12. rows = list(csv.DictReader(handle))
  13. daily = defaultdict(list)
  14. for row in rows:
  15. day = row["sample_time"][:10]
  16. if not "2026-03-01" <= day < "2026-04-20":
  17. continue
  18. if (unit, row["cylinder"], row["side"]) in {("7", "四", "盖侧"), ("7", "六", "盖侧"), ("8", "六", "盖侧")}:
  19. continue
  20. if float(row["p_span"]) < .3:
  21. continue
  22. keys = ["p_suction", "p_discharge", "p_span"] + [f"prof_{i:02d}" for i in range(12)]
  23. vector = np.array([float(row[k]) for k in keys])
  24. if np.all(np.isfinite(vector)):
  25. daily[(row["cylinder"], row["side"], day)].append(vector)
  26. for point in sorted({(c, s) for c, s, _ in daily}):
  27. periods = []
  28. for start, end in [("2026-03-01", "2026-03-21"), ("2026-03-21", "2026-04-01"), ("2026-04-01", "2026-04-20")]:
  29. selected = [(day, values) for (c, s, day), values in daily.items() if (c, s) == point and start <= day < end]
  30. median = np.median([np.median(values, axis=0) for _, values in selected], axis=0) if selected else None
  31. periods.append((selected, median))
  32. for label, index in [("3月上中旬至3月下旬", 1), ("3月上中旬至4月", 2)]:
  33. before, a = periods[0]
  34. after, b = periods[index]
  35. if a is None or b is None:
  36. continue
  37. delta = b - a
  38. result = {"机组": unit, "测点": f"{point[0]}缸{point[1]}", "对照": label,
  39. "前段日期": "/".join(sorted(d for d, _ in before)), "后段日期": "/".join(sorted(d for d, _ in after)),
  40. "前段周期": sum(len(v) for _, v in before), "后段周期": sum(len(v) for _, v in after),
  41. "吸气变化": round(delta[0], 5), "排气变化": round(delta[1], 5),
  42. "幅度变化": round(delta[2], 5), "形状距离12点": round(float(np.linalg.norm(delta[3:])), 5)}
  43. output.append(result)
  44. print(f"{unit}号")
  45. for label in ("3月上中旬至3月下旬", "3月上中旬至4月"):
  46. selected = [r for r in output if r["机组"] == unit and r["对照"] == label]
  47. print(label, "测点", len(selected))
  48. for key in ("吸气变化", "排气变化", "幅度变化"):
  49. print(key, "中位", round(float(np.median([r[key] for r in selected])), 5) if selected else None,
  50. "上升", sum(r[key] > 0 for r in selected))
  51. print("形状变化", sorted([(r["测点"], r["形状距离12点"]) for r in selected], key=lambda v: -v[1]))
  52. with (root / "春季同期跨机组对照.csv").open("w", encoding="utf-8-sig", newline="") as handle:
  53. writer = csv.DictWriter(handle, fieldnames=list(output[0]))
  54. writer.writeheader()
  55. writer.writerows(output)
  56. if __name__ == "__main__":
  57. main()