Download features.py from bardd/forecast: direct link, hf CLI and curl.
- Browser
- Download file 2.09 kB
-
https://huggingface.co/spaces/bardd/forecast/resolve/main/features.py
- Command line
-
hf download hf://spaces/bardd/forecast/features.py
-
curl -L -o features.py https://huggingface.co/spaces/bardd/forecast/resolve/main/features.py
2.09 kB
| """Tiny feature builder for the review pack (no weather, no API calls). | |
| Reads data/*.csv, adds calendar + shift-safe lags/rolls. Plain pandas. | |
| """ | |
| import pandas as pd | |
| FEATS_CAT = ["Area", "Region"] | |
| FEATS_NUM = ["dow", "is_friday", "is_saturday", "is_weekend", "dom", "month", | |
| "year", "woy", "days_since_start", "is_closure", "is_event_date", | |
| "lag_1", "lag_7", "lag_14", "lag_28", "lag_56", | |
| "roll_mean_7", "roll_mean_28", "roll_std_28", "nonzero_rate_28"] | |
| FEATS = FEATS_CAT + FEATS_NUM | |
| def build(csv_path): | |
| df = pd.read_csv(csv_path, parse_dates=["Date"]) | |
| df = df.sort_values(["Area", "Date"]).reset_index(drop=True) | |
| df["dow"] = df["Date"].dt.dayofweek.astype("int8") | |
| df["is_friday"] = (df["dow"] == 4).astype("int8") | |
| df["is_saturday"] = (df["dow"] == 5).astype("int8") | |
| df["is_weekend"] = (df["dow"] >= 4).astype("int8") | |
| df["dom"] = df["Date"].dt.day.astype("int8") | |
| df["month"] = df["Date"].dt.month.astype("int8") | |
| df["year"] = df["Date"].dt.year.astype("int16") | |
| df["woy"] = df["Date"].dt.isocalendar().week.astype("int16") | |
| df["days_since_start"] = (df["Date"] - df["Date"].min()).dt.days.astype("int16") | |
| df["Area"] = df["Area"].astype("category") | |
| df["Region"] = df["Region"].astype("category") | |
| for lag in [1, 7, 14, 28, 56]: | |
| df[f"lag_{lag}"] = df.groupby("Area", observed=True)["Volume"].shift(lag).astype("float32") | |
| g = df.groupby("Area", observed=True)["Volume"] | |
| df["roll_mean_7"] = g.transform(lambda s: s.shift(1).rolling(7).mean()).astype("float32") | |
| df["roll_mean_28"] = g.transform(lambda s: s.shift(1).rolling(28).mean()).astype("float32") | |
| df["roll_std_28"] = g.transform(lambda s: s.shift(1).rolling(28).std()).astype("float32") | |
| df["nonzero_rate_28"] = g.transform( | |
| lambda s: s.shift(1).rolling(28).apply(lambda w: (w > 0).mean(), raw=True)).astype("float32") | |
| return df | |
| def wape(y, p): | |
| import numpy as np | |
| y = np.asarray(y, dtype=float) | |
| p = np.asarray(p, dtype=float) | |
| return float(abs(y - p).sum() / max(abs(y).sum(), 1e-9)) | |