Files
ts-anomaly-td/ts_anomaly_td/io_csv.py
T

60 lines
2.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""CSV 读取模块:读 timestamp,value,label 三列,返回归一化元组。"""
from pathlib import Path
import pandas as pd
def read_csv(path: str | Path, value_col: str = "value") -> tuple[list[int], list[float], list[int]]:
"""读 timestamp,value,label CSV 文件。
Args:
path: CSV 文件路径
value_col: 数值列名 (default: "value")
Returns:
(timestamps_ms, values, labels) 三元组
- timestamps_ms: 毫秒精度 Unix 时间戳
- values: 浮点数值列表
- labels: 整数标签列表(0=正常, 1=异常)
Raises:
FileNotFoundError: 文件不存在
ValueError: 缺少 timestamp 或 value 列
"""
df = pd.read_csv(path)
if "timestamp" not in df.columns or value_col not in df.columns:
raise ValueError(f"CSV 缺少 timestamp 或 {value_col} 列: {path}")
timestamps = pd.to_datetime(df["timestamp"], format="mixed", errors="coerce")
if timestamps.isna().any():
# 对无法解析的行尝试修正(如 00:60:00 → 01:00:00
import re
na_mask = timestamps.isna()
raw_strs = df.loc[na_mask, "timestamp"].astype(str)
def _fix_hour60(s: str) -> str:
def _repl(m):
h = (int(m.group(1)) + 1) % 24
return f"{h:02d}:00:00"
return re.sub(r"(\d{2}):60:00", _repl, s)
fixed = raw_strs.apply(_fix_hour60)
timestamps.loc[na_mask] = pd.to_datetime(fixed, errors="coerce")
# 丢弃时间戳仍为 NaN 的行(coerce 后无法恢复的异常时间戳)
valid_mask = timestamps.notna()
if not valid_mask.all():
n_drop = (~valid_mask).sum()
import logging
logging.getLogger(__name__).warning("dropping %d rows with invalid timestamps", n_drop)
timestamps = timestamps[valid_mask].reset_index(drop=True)
df = df[valid_mask].reset_index(drop=True)
timestamps_ms = (timestamps.astype("int64") // 10**6).tolist()
values = df[value_col].astype(float).tolist()
labels = df["label"].fillna(0).astype(int).tolist() if "label" in df.columns else [0] * len(df)
return timestamps_ms, values, labels