- Source
- NYC TLC, yellow taxi
- Period
- January 2022, weekdays
- Raw trips
- 2,463,931
- Kept
- 300,000 between the 20 busiest zones
- Split
- by day: train Jan 3 to 19, validation 20 to 21, test 24 to 31
- Seed
- 42
make_data.py
Also: delivery/data.py delivery/instances.py delivery/config.py
make_data.py
"""Download + preprocess the NYC TLC data and build the generated instance set.
python make_data.py # uses cached raw files if present
python make_data.py --force # re-download
Outputs: data/processed/* (gitignored), tests/fixtures/* (small, committed),
instances/*.json (generated orders, committed).
"""
import argparse
import json
import shutil
from delivery import config as C
from delivery import data as D
from delivery.instances import generate_instance
def disk_guard(min_free_mb=150):
free = shutil.disk_usage(C.ROOT).free / 1e6
print(f" free disk: {free:,.0f} MB")
if free < min_free_mb:
raise SystemExit(f"stopping: less than {min_free_mb} MB free on the project drive")
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--force", action="store_true")
args = ap.parse_args()
print("[1/5] download"); disk_guard()
paths = D.download(force=args.force); disk_guard()
print("[2/5] read + check schema")
raw = D.load_raw_trips(paths["trips"])
import pandas as pd
lookup = pd.read_csv(paths["lookup"])
cents = D.zone_centroids(paths["shapes"])
print(f" {len(raw):,} raw rows, columns OK: {D.NEEDED_COLS}")
print("[3/5] filter, top zones, sample, split by day")
trips, zones, stats = D.preprocess(raw, lookup, cents)
for k, v in stats.items():
if not isinstance(v, list):
print(f" {k:>22}: {v:,}")
print(" zones:", ", ".join(zones.zone))
print("[4/5] zone-pair mean distance (train only)")
dist, cnt, fit = D.pair_distance_matrix(trips, zones)
stats["pair_distance_fallback"] = fit
tr = trips[trips.split == "train"]
g = tr.groupby(["pu", "do", "hour"]).size()
stats["rare_cells_lt5_train"] = int((g < 5).sum())
stats["cells_possible"] = len(zones) ** 2 * 24
stats["cells_seen_train"] = int(len(g))
night = tr[tr.hour < 6].groupby(["pu", "do"]).size()
stats["night_pairs_seen_train"] = int(len(night))
D.save_processed(trips, zones, dist, cnt, stats)
D.write_fixture(trips, zones, dist)
print(f" unseen pairs filled by fit: {fit['unseen_pairs']}; "
f"(pu,do,hour) cells seen {stats['cells_seen_train']}/{stats['cells_possible']}, "
f"rare (<5 trips) {stats['rare_cells_lt5_train']}")
print("[5/5] generated instance set")
C.INSTANCES.mkdir(exist_ok=True)
weights = zones.sort_values("idx").n_dropoffs.values
manifest = []
for n in (15, 20, 30):
for seed in range(10):
inst = generate_instance(n, seed, n_zones=len(zones), zone_weights=weights)
p = C.INSTANCES / f"{inst.name}.json"
inst.save(p); manifest.append(p.name)
(C.INSTANCES / "manifest.json").write_text(json.dumps(manifest, indent=1))
print(f" wrote {len(manifest)} instances to instances/")
disk_guard()
if __name__ == "__main__":
main()