from __future__ import annotations import numpy as np def moving_average(values: list[float], window: int = 5) -> list[float]: if len(values) < window: return values arr = np.array(values, dtype=float) return np.convolve(arr, np.ones(window) / window, mode="valid").tolist() def detect_anomalies( values: list[float], threshold: float = 2.0 ) -> list[dict]: """Detect anomalies using Z-score method.""" arr = np.array(values, dtype=float) mean = np.mean(arr) std = np.std(arr) if std == 0: return [] z_scores = np.abs((arr - mean) / std) anomalies = [] for i, (val, z) in enumerate(zip(values, z_scores)): if z > threshold: anomalies.append({"index": i, "value": val, "z_score": float(z)}) return anomalies def percentile_stats(values: list[float]) -> dict: arr = np.array(values, dtype=float) return { "p50": float(np.percentile(arr, 50)), "p90": float(np.percentile(arr, 90)), "p95": float(np.percentile(arr, 95)), "p99": float(np.percentile(arr, 99)), }