sofsof / app.py
liry1312's picture
Rename app-2.py to app.py
4ef1ac5 verified
raw
history blame
7.35 kB
import gradio as gr
import pandas as pd
import numpy as np
CSV_FILE = "all-vehicles-model@public.csv"
# 注诪讜讚讜转 讞砖讜讘讜转 诪转讜讱 讛讚讗讟讛
COLS = {
"make": "Make",
"model": "Model",
"fuel1": "Fuel Type1",
"fuel_any": "Fuel Type",
"drive": "Drive",
"trans": "Transmission",
"cyl": "Cylinders",
"disp": "Engine displacement",
"mpg_city_f1": "City Mpg For Fuel Type1",
"mpg_hwy_f1": "Highway Mpg For Fuel Type1",
"mpg_comb_f1": "Combined Mpg For Fuel Type1",
"mpg_city_f2": "City Mpg For Fuel Type2",
"mpg_hwy_f2": "Highway Mpg For Fuel Type2",
"mpg_comb_f2": "Combined Mpg For Fuel Type2",
"annual_fuel_cost_f1": "Annual Fuel Cost For Fuel Type1",
"annual_fuel_cost_f2": "Annual Fuel Cost For Fuel Type2",
"ev_range_f2": "Epa Range For Fuel Type2",
"charge_240": "Time to charge at 240V",
"co2_f1": "Co2 Fuel Type1",
"co2_tailpipe_f1": "Co2 Tailpipe For Fuel Type1",
"hatch_lug": "Hatchback luggage volume",
"hatch_pass": "Hatchback passenger volume",
"year": "Year"
}
def load_data():
df = pd.read_csv(CSV_FILE, sep=";", encoding="utf-8", engine="python")
# 讛诪专讜转 讟讬驻讜住 讘住讬住讬讜转
for c in ["City Mpg For Fuel Type1", "Highway Mpg For Fuel Type1", "Combined Mpg For Fuel Type1",
"City Mpg For Fuel Type2", "Highway Mpg For Fuel Type2", "Combined Mpg For Fuel Type2",
"Annual Fuel Cost For Fuel Type1", "Annual Fuel Cost For Fuel Type2",
"Epa Range For Fuel Type2", "Time to charge at 240V", "Cylinders", "Engine displacement",
"Hatchback luggage volume", "Hatchback passenger volume"]:
if c in df.columns:
df[c] = pd.to_numeric(df[c], errors="coerce")
# 讛讜专讚转 讻驻讬诇讜讬讜转 讘住讬住讬转
keep_cols = [v for v in COLS.values() if v in df.columns]
subset = [c for c in keep_cols if c in ["Make","Model","Year"]]
if subset:
df = df.drop_duplicates(subset=subset)
return df
DF = load_data()
def options_safe(col):
if col in DF.columns:
vals = DF[col].dropna().astype(str).str.strip().replace("", np.nan).dropna().unique().tolist()
vals = [v for v in vals if v.lower() not in {"nan","none"}]
vals.sort()
return vals[:50]
return []
FUEL_OPTS = sorted(set([*options_safe(COLS["fuel1"]), *options_safe(COLS["fuel_any"]), "No preference"]))
DRIVE_OPTS = [*options_safe(COLS["drive"]), "No preference"]
TRANS_OPTS = [*options_safe(COLS["trans"]), "No preference"]
def recommend(budget_fuel_per_year, usage, daily_km, seats_min, fuel_pref, drive_pref, trans_pref, cargo_need, perf_pref):
df = DF.copy()
# 住讬谞讜谞讬诐 诇驻讬 讛注讚驻讜转
if fuel_pref and fuel_pref != "No preference":
df = df[(df.get(COLS["fuel1"], "").astype(str).str.contains(fuel_pref, case=False, na=False)) |
(df.get(COLS["fuel_any"], "").astype(str).str.contains(fuel_pref, case=False, na=False))]
if drive_pref and drive_pref != "No preference" and COLS["drive"] in df.columns:
df = df[df[COLS["drive"]].astype(str).str.contains(drive_pref, case=False, na=False)]
if trans_pref and trans_pref != "No preference" and COLS["trans"] in df.columns:
df = df[df[COLS["trans"]].astype(str).str.contains(trans_pref, case=False, na=False)]
def norm(s):
s = pd.to_numeric(s, errors="coerce")
return (s - s.min()) / (s.max() - s.min() + 1e-9)
# 讬注讬诇讜转 讚诇拽 诇驻讬 砖讬诪讜砖
if usage == "注讬专":
eff = df.get(COLS["mpg_city_f1"], df.get(COLS["mpg_comb_f1"]))
elif usage == "讘讬谞注讬专讜谞讬":
eff = df.get(COLS["mpg_hwy_f1"], df.get(COLS["mpg_comb_f1"]))
else:
eff = df.get(COLS["mpg_comb_f1"])
eff_score = norm(eff) if eff is not None else pd.Series(0, index=df.index)
# 注诇讜转 讚诇拽 砖谞转讬转 谞诪讜讻讛 注讚讬驻讛
fuel_cost = df.get(COLS["annual_fuel_cost_f1"])
fuel_cost_score = 1 - norm(fuel_cost) if fuel_cost is not None else pd.Series(0.5, index=df.index)
# 讛转讗诪转 EV 诇驻讬 讟讜讜讞 讜谞住讜注讛 讬讜诪讬转
ev_range = df.get(COLS["ev_range_f2"])
if ev_range is not None and daily_km:
ev_ok = (ev_range >= (daily_km * 0.62 * 3)) # 拽"诪 诇诪讬讬诇, 驻讬 3 诪专讜讜讞 讘讬讟讞讜谉
ev_score = ev_ok.astype(float)
else:
ev_score = pd.Series(0.5, index=df.index)
# 谞驻讞 诪讟注谉
cargo = df.get(COLS["hatch_lug"])
cargo_score = norm(cargo) if (cargo is not None and cargo_need) else pd.Series(0.5, index=df.index)
# 讘讬爪讜注讬诐 诪讜诇 讞住讻讜谉 诇驻讬 爪讬诇讬谞讚专讬诐 讜谞驻讞 诪谞讜注
cyl = df.get(COLS["cyl"]); disp = df.get(COLS["disp"])
perf_raw = norm(cyl).fillna(0.5) * 0.5 + norm(disp).fillna(0.5) * 0.5
econ_raw = 1 - perf_raw
perf_mix = perf_pref * perf_raw + (1 - perf_pref) * econ_raw
# 诪砖拽讜诇讜转
w_eff = 0.3
w_cost = 0.25
w_ev = 0.15
w_cargo = 0.1
w_perf = 0.2
score = w_eff*eff_score.fillna(0.5) + w_cost*fuel_cost_score.fillna(0.5) + w_ev*ev_score.fillna(0.5) + \
w_cargo*cargo_score.fillna(0.5) + w_perf*perf_mix.fillna(0.5)
df_out = df.copy()
df_out["Score"] = score.round(4)
show_cols = [c for c in [
COLS["make"], COLS["model"], "Year" if "Year" in df.columns else None,
COLS["fuel1"] if COLS["fuel1"] in df.columns else COLS["fuel_any"],
COLS["drive"], COLS["trans"],
COLS["mpg_city_f1"], COLS["mpg_hwy_f1"], COLS["mpg_comb_f1"],
COLS["annual_fuel_cost_f1"], COLS["ev_range_f2"],
COLS["cyl"], COLS["disp"],
"Score"
] if (c and (c in df.columns)) or c=="Score"]
return df_out.sort_values("Score", ascending=False).head(10)[show_cols]
with gr.Blocks(title="诪诪诇讬抓 专讻讘讬诐") as demo:
gr.Markdown("# 诪诪诇讬抓 专讻讘讬诐 讞讻诐\n讛讗驻诇讬拽爪讬讛 诪转讗讬诪讛 讚讙诪讬诐 诇爪专讻讬诐 砖诇讱 注诇 讘住讬住 讚讗讟讛 砖诇 EPA.\n")
with gr.Row():
usage = gr.Radio(["注讬专", "讘讬谞注讬专讜谞讬", "诪注讜专讘"], value="诪注讜专讘", label="讗讜驻讬 砖讬诪讜砖")
daily_km = gr.Slider(0, 200, value=30, step=5, label="谞住讜注讛 讬讜诪讬转 诪诪讜爪注转 讘拽讬诇讜诪讟专讬诐")
budget_fuel = gr.Slider(0, 6000, value=3000, step=100, label="转拽爪讬讘 讚诇拽 讗讜 讞砖诪诇 砖谞转讬")
with gr.Row():
fuel_pref = gr.Dropdown(choices=FUEL_OPTS, value="No preference", label="注讚讬驻讜转 诇住讜讙 讚诇拽")
drive_pref = gr.Dropdown(choices=DRIVE_OPTS, value="No preference", label="讛谞注讛")
trans_pref = gr.Dropdown(choices=TRANS_OPTS, value="No preference", label="转讬讘转 讛讬诇讜讻讬诐")
with gr.Row():
cargo_need = gr.Slider(0, 800, value=0, step=20, label="谞驻讞 诪讟注谉 诪讬谞讬诪诇讬 专爪讜讬")
perf_pref = gr.Slider(0, 1, value=0.4, step=0.05, label="注讚讬驻讜转 0 讞住讻讜谉 1 讘讬爪讜注讬诐")
seats_min = gr.Slider(2, 8, value=4, step=1, label="诪讜砖讘讬诐 诪讬谞讬诪讜诐")
btn = gr.Button("诪爪讗 专讻讘讬诐")
out = gr.Dataframe(interactive=False, wrap=True, label="讛转讗诪讜转 诪讜诪诇爪讜转 . 讟讜驻 10")
btn.click(fn=recommend,
inputs=[budget_fuel, usage, daily_km, seats_min, fuel_pref, drive_pref, trans_pref, cargo_need, perf_pref],
outputs=out)
demo.queue().launch()