feat: add io_csv module with CSV reader and tests

This commit is contained in:
张宗平
2026-06-11 15:32:30 +08:00
parent 1c1233bddd
commit 0788daf2af
5 changed files with 18742 additions and 0 deletions
+1625
View File
File diff suppressed because it is too large Load Diff
+1110
View File
File diff suppressed because it is too large Load Diff
+15903
View File
File diff suppressed because it is too large Load Diff
+69
View File
@@ -0,0 +1,69 @@
"""io_csv 模块测试。"""
import tempfile
from pathlib import Path
import pytest
from ts_anomaly_td.io_csv import read_csv
def test_read_csv_basic():
"""基本读取:三列完整。"""
content = "timestamp,value,label\n2020-01-01 00:00:00,1.0,0\n2020-01-01 01:00:00,2.0,1\n"
with tempfile.NamedTemporaryFile(mode="w", suffix=".csv", delete=False) as f:
f.write(content)
tmp = f.name
try:
ts, vals, labels = read_csv(tmp)
assert len(ts) == 2
assert len(vals) == 2
assert len(labels) == 2
assert vals[0] == 1.0
assert labels[1] == 1
finally:
Path(tmp).unlink()
def test_read_csv_no_label_column():
"""label 列缺失时填 0。"""
content = "timestamp,value\n2020-01-01 00:00:00,5.0\n"
with tempfile.NamedTemporaryFile(mode="w", suffix=".csv", delete=False) as f:
f.write(content)
tmp = f.name
try:
ts, vals, labels = read_csv(tmp)
assert labels == [0]
finally:
Path(tmp).unlink()
def test_read_csv_missing_required_column():
"""缺少 timestamp 或 value 列时抛出 ValueError。"""
content = "time,val\n2020-01-01,1.0\n"
with tempfile.NamedTemporaryFile(mode="w", suffix=".csv", delete=False) as f:
f.write(content)
tmp = f.name
try:
with pytest.raises(ValueError):
read_csv(tmp)
finally:
Path(tmp).unlink()
def test_read_csv_file_not_found():
"""文件不存在抛出 FileNotFoundError。"""
with pytest.raises(FileNotFoundError):
read_csv("/nonexistent/file.csv")
def test_read_csv_finance_001():
"""验证真实 finance_001.csv 可读。"""
path = Path(__file__).parent.parent / "data" / "finance_001.csv"
if not path.exists():
pytest.skip("finance_001.csv not found")
ts, vals, labels = read_csv(str(path))
assert len(ts) == len(vals) == len(labels)
assert len(ts) > 0
assert all(isinstance(v, float) for v in vals)
+35
View File
@@ -0,0 +1,35 @@
"""CSV 读取模块:读 timestamp,value,label 三列,返回归一化元组。"""
from pathlib import Path
import pandas as pd
def read_csv(path: str | Path) -> tuple[list[int], list[float], list[int]]:
"""读 timestamp,value,label CSV 文件。
Args:
path: CSV 文件路径
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" not in df.columns:
raise ValueError(f"CSV 缺少 timestamp 或 value 列: {path}")
timestamps = pd.to_datetime(df["timestamp"])
timestamps_ms = (timestamps.astype("int64") // 10**6).tolist()
values = df["value"].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