Spaces:
Running
Running
Download space/vendor/ts_bench/export_model_inputs.py from ThinkcatLab/LiveHouse-TS: direct link, hf CLI and curl.
- Browser
- Download file 5.64 kB
-
https://huggingface.co/spaces/ThinkcatLab/LiveHouse-TS/resolve/main/space/vendor/ts_bench/export_model_inputs.py
- Command line
-
hf download hf://spaces/ThinkcatLab/LiveHouse-TS/space/vendor/ts_bench/export_model_inputs.py
-
curl -L -o export_model_inputs.py https://huggingface.co/spaces/ThinkcatLab/LiveHouse-TS/resolve/main/space/vendor/ts_bench/export_model_inputs.py
5.64 kB
| #!/usr/bin/env python3 | |
| """Export task-level model input CSV files from normalized TS-Bench tables. | |
| This script does not fetch data. It reads: | |
| normalized/observations.csv | |
| normalized/forecast_tasks.csv | |
| For each task it writes: | |
| model_inputs/<task_id>/context.csv | |
| model_inputs/<task_id>/future_target.csv | |
| The context file is what a model can consume. The future_target file is only | |
| for evaluator/scoring code. | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import csv | |
| import json | |
| import sys | |
| from collections import defaultdict | |
| from datetime import datetime, timezone | |
| from pathlib import Path | |
| from typing import Any, Dict, Iterable, List, Tuple | |
| UTC = timezone.utc | |
| def parse_dt(value: str) -> datetime: | |
| text = value.strip() | |
| if text.endswith("Z"): | |
| text = text[:-1] + "+00:00" | |
| dt = datetime.fromisoformat(text) | |
| if dt.tzinfo is None: | |
| dt = dt.replace(tzinfo=UTC) | |
| return dt.astimezone(UTC) | |
| def read_csv(path: Path) -> List[Dict[str, str]]: | |
| with path.open("r", newline="", encoding="utf-8") as handle: | |
| return list(csv.DictReader(handle)) | |
| def write_csv(path: Path, rows: Iterable[Dict[str, Any]], fieldnames: List[str]) -> int: | |
| path.parent.mkdir(parents=True, exist_ok=True) | |
| count = 0 | |
| with path.open("w", newline="", encoding="utf-8") as handle: | |
| writer = csv.DictWriter(handle, fieldnames=fieldnames) | |
| writer.writeheader() | |
| for row in rows: | |
| writer.writerow({name: row.get(name, "") for name in fieldnames}) | |
| count += 1 | |
| return count | |
| def pivot_rows(rows: List[Dict[str, str]]) -> Tuple[List[Dict[str, Any]], List[str]]: | |
| grouped: Dict[str, Dict[str, Any]] = {} | |
| variables = sorted({row["variable_id"] for row in rows}) | |
| for row in rows: | |
| timestamp = row["timestamp"] | |
| if timestamp not in grouped: | |
| grouped[timestamp] = {"timestamp": timestamp} | |
| grouped[timestamp][row["variable_id"]] = row["value"] | |
| return [grouped[key] for key in sorted(grouped)], ["timestamp"] + variables | |
| def export_task( | |
| task: Dict[str, str], | |
| observations: List[Dict[str, str]], | |
| output_root: Path, | |
| ) -> Dict[str, Any]: | |
| dataset_id = task["dataset_id"] | |
| entity_id = task["target_entity_id"] | |
| target_variable_id = task["target_variable_id"] | |
| forecast_issue_time = parse_dt(task["forecast_issue_time"]) | |
| context_start = parse_dt(task["context_start"]) | |
| context_end = parse_dt(task["context_end"]) | |
| horizon_start = parse_dt(task["horizon_start"]) | |
| horizon_end = parse_dt(task["horizon_end"]) | |
| context_rows = [] | |
| future_rows = [] | |
| for row in observations: | |
| if row["dataset_id"] != dataset_id or row["entity_id"] != entity_id: | |
| continue | |
| timestamp = parse_dt(row["timestamp"]) | |
| available_time = parse_dt(row["available_time"]) | |
| if context_start <= timestamp <= context_end and available_time <= forecast_issue_time: | |
| context_rows.append(row) | |
| if horizon_start <= timestamp <= horizon_end and row["variable_id"] == target_variable_id: | |
| future_rows.append(row) | |
| context_pivot, context_fields = pivot_rows(context_rows) | |
| future_pivot, future_fields = pivot_rows(future_rows) | |
| task_dir = output_root / task["task_id"] | |
| context_count = write_csv(task_dir / "context.csv", context_pivot, context_fields) | |
| future_count = write_csv(task_dir / "future_target.csv", future_pivot, future_fields) | |
| (task_dir / "task.json").write_text(json.dumps(task, ensure_ascii=False, indent=2), encoding="utf-8") | |
| return { | |
| "task_id": task["task_id"], | |
| "dataset_id": dataset_id, | |
| "entity_id": entity_id, | |
| "target_variable_id": target_variable_id, | |
| "context_rows": context_count, | |
| "future_target_rows": future_count, | |
| "context_csv": str(task_dir / "context.csv"), | |
| "future_target_csv": str(task_dir / "future_target.csv"), | |
| } | |
| def parse_args(argv: List[str]) -> argparse.Namespace: | |
| parser = argparse.ArgumentParser(description="Export model input CSVs from normalized TS-Bench tables.") | |
| parser.add_argument("--input", default="data/sample_week/normalized", help="Directory containing normalized CSV tables.") | |
| parser.add_argument("--output", default="data/sample_week/model_inputs", help="Output directory for task-level model inputs.") | |
| parser.add_argument("--limit", type=int, default=20, help="Maximum number of tasks to export.") | |
| return parser.parse_args(argv) | |
| def main(argv: List[str]) -> int: | |
| args = parse_args(argv) | |
| input_dir = Path(args.input) | |
| output_dir = Path(args.output) | |
| observations_path = input_dir / "observations.csv" | |
| tasks_path = input_dir / "forecast_tasks.csv" | |
| if not observations_path.exists() or not tasks_path.exists(): | |
| raise FileNotFoundError(f"Expected {observations_path} and {tasks_path}") | |
| observations = read_csv(observations_path) | |
| tasks = read_csv(tasks_path)[: args.limit] | |
| manifest = [export_task(task, observations, output_dir) for task in tasks] | |
| write_csv( | |
| output_dir / "manifest.csv", | |
| manifest, | |
| [ | |
| "task_id", | |
| "dataset_id", | |
| "entity_id", | |
| "target_variable_id", | |
| "context_rows", | |
| "future_target_rows", | |
| "context_csv", | |
| "future_target_csv", | |
| ], | |
| ) | |
| (output_dir / "manifest.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding="utf-8") | |
| print(f"Exported {len(manifest)} tasks to {output_dir}") | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main(sys.argv[1:])) | |