liry1312 commited on
Commit
fb254fc
verified
1 Parent(s): a782b4f

Upload 2 files

Browse files
Files changed (2) hide show
  1. app-2.py +162 -0
  2. requirements-2.txt +3 -0
app-2.py ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import gradio as gr
3
+ import pandas as pd
4
+ import numpy as np
5
+
6
+ CSV_FILE = "all-vehicles-model@public.csv"
7
+
8
+ # 注诪讜讚讜转 讞砖讜讘讜转 诪转讜讱 讛讚讗讟讛
9
+ COLS = {
10
+ "make": "Make",
11
+ "model": "Model",
12
+ "fuel1": "Fuel Type1",
13
+ "fuel_any": "Fuel Type",
14
+ "drive": "Drive",
15
+ "trans": "Transmission",
16
+ "cyl": "Cylinders",
17
+ "disp": "Engine displacement",
18
+ "mpg_city_f1": "City Mpg For Fuel Type1",
19
+ "mpg_hwy_f1": "Highway Mpg For Fuel Type1",
20
+ "mpg_comb_f1": "Combined Mpg For Fuel Type1",
21
+ "mpg_city_f2": "City Mpg For Fuel Type2",
22
+ "mpg_hwy_f2": "Highway Mpg For Fuel Type2",
23
+ "mpg_comb_f2": "Combined Mpg For Fuel Type2",
24
+ "annual_fuel_cost_f1": "Annual Fuel Cost For Fuel Type1",
25
+ "annual_fuel_cost_f2": "Annual Fuel Cost For Fuel Type2",
26
+ "ev_range_f2": "Epa Range For Fuel Type2",
27
+ "charge_240": "Time to charge at 240V",
28
+ "co2_f1": "Co2 Fuel Type1",
29
+ "co2_tailpipe_f1": "Co2 Tailpipe For Fuel Type1",
30
+ "hatch_lug": "Hatchback luggage volume",
31
+ "hatch_pass": "Hatchback passenger volume",
32
+ "year": "Year"
33
+ }
34
+
35
+ def load_data():
36
+ df = pd.read_csv(CSV_FILE, sep=";", encoding="utf-8", engine="python")
37
+ # 讛诪专讜转 讟讬驻讜住 讘住讬住讬讜转
38
+ for c in ["City Mpg For Fuel Type1", "Highway Mpg For Fuel Type1", "Combined Mpg For Fuel Type1",
39
+ "City Mpg For Fuel Type2", "Highway Mpg For Fuel Type2", "Combined Mpg For Fuel Type2",
40
+ "Annual Fuel Cost For Fuel Type1", "Annual Fuel Cost For Fuel Type2",
41
+ "Epa Range For Fuel Type2", "Time to charge at 240V", "Cylinders", "Engine displacement",
42
+ "Hatchback luggage volume", "Hatchback passenger volume"]:
43
+ if c in df.columns:
44
+ df[c] = pd.to_numeric(df[c], errors="coerce")
45
+ # 讛讜专讚转 讻驻讬诇讜讬讜转 讘住讬住讬转
46
+ keep_cols = [v for v in COLS.values() if v in df.columns]
47
+ subset = [c for c in keep_cols if c in ["Make","Model","Year"]]
48
+ if subset:
49
+ df = df.drop_duplicates(subset=subset)
50
+ return df
51
+
52
+ DF = load_data()
53
+
54
+ def options_safe(col):
55
+ if col in DF.columns:
56
+ vals = DF[col].dropna().astype(str).str.strip().replace("", np.nan).dropna().unique().tolist()
57
+ vals = [v for v in vals if v.lower() not in {"nan","none"}]
58
+ vals.sort()
59
+ return vals[:50]
60
+ return []
61
+
62
+ FUEL_OPTS = sorted(set([*options_safe(COLS["fuel1"]), *options_safe(COLS["fuel_any"]), "No preference"]))
63
+ DRIVE_OPTS = [*options_safe(COLS["drive"]), "No preference"]
64
+ TRANS_OPTS = [*options_safe(COLS["trans"]), "No preference"]
65
+
66
+ def recommend(budget_fuel_per_year, usage, daily_km, seats_min, fuel_pref, drive_pref, trans_pref, cargo_need, perf_pref):
67
+ df = DF.copy()
68
+
69
+ # 住讬谞讜谞讬诐 诇驻讬 讛注讚驻讜转
70
+ if fuel_pref and fuel_pref != "No preference":
71
+ df = df[(df.get(COLS["fuel1"], "").astype(str).str.contains(fuel_pref, case=False, na=False)) |
72
+ (df.get(COLS["fuel_any"], "").astype(str).str.contains(fuel_pref, case=False, na=False))]
73
+ if drive_pref and drive_pref != "No preference" and COLS["drive"] in df.columns:
74
+ df = df[df[COLS["drive"]].astype(str).str.contains(drive_pref, case=False, na=False)]
75
+ if trans_pref and trans_pref != "No preference" and COLS["trans"] in df.columns:
76
+ df = df[df[COLS["trans"]].astype(str).str.contains(trans_pref, case=False, na=False)]
77
+
78
+ def norm(s):
79
+ s = pd.to_numeric(s, errors="coerce")
80
+ return (s - s.min()) / (s.max() - s.min() + 1e-9)
81
+
82
+ # 讬注讬诇讜转 讚诇拽 诇驻讬 砖讬诪讜砖
83
+ if usage == "注讬专":
84
+ eff = df.get(COLS["mpg_city_f1"], df.get(COLS["mpg_comb_f1"]))
85
+ elif usage == "讘讬谞注讬专讜谞讬":
86
+ eff = df.get(COLS["mpg_hwy_f1"], df.get(COLS["mpg_comb_f1"]))
87
+ else:
88
+ eff = df.get(COLS["mpg_comb_f1"])
89
+ eff_score = norm(eff) if eff is not None else pd.Series(0, index=df.index)
90
+
91
+ # 注诇讜转 讚诇拽 砖谞转讬转 谞诪讜讻讛 注讚讬驻讛
92
+ fuel_cost = df.get(COLS["annual_fuel_cost_f1"])
93
+ fuel_cost_score = 1 - norm(fuel_cost) if fuel_cost is not None else pd.Series(0.5, index=df.index)
94
+
95
+ # 讛转讗诪转 EV 诇驻讬 讟讜讜讞 讜谞住讜注讛 讬讜诪讬转
96
+ ev_range = df.get(COLS["ev_range_f2"])
97
+ if ev_range is not None and daily_km:
98
+ ev_ok = (ev_range >= (daily_km * 0.62 * 3)) # 拽"诪 诇诪讬讬诇, 驻讬 3 诪专讜讜讞 讘讬讟讞讜谉
99
+ ev_score = ev_ok.astype(float)
100
+ else:
101
+ ev_score = pd.Series(0.5, index=df.index)
102
+
103
+ # 谞驻讞 诪讟注谉
104
+ cargo = df.get(COLS["hatch_lug"])
105
+ cargo_score = norm(cargo) if (cargo is not None and cargo_need) else pd.Series(0.5, index=df.index)
106
+
107
+ # 讘讬爪讜注讬诐 诪讜诇 讞住讻讜谉 诇驻讬 爪讬诇讬谞讚专讬诐 讜谞驻讞 诪谞讜注
108
+ cyl = df.get(COLS["cyl"]); disp = df.get(COLS["disp"])
109
+ perf_raw = norm(cyl).fillna(0.5) * 0.5 + norm(disp).fillna(0.5) * 0.5
110
+ econ_raw = 1 - perf_raw
111
+ perf_mix = perf_pref * perf_raw + (1 - perf_pref) * econ_raw
112
+
113
+ # 诪砖拽讜诇讜转
114
+ w_eff = 0.3
115
+ w_cost = 0.25
116
+ w_ev = 0.15
117
+ w_cargo = 0.1
118
+ w_perf = 0.2
119
+
120
+ score = w_eff*eff_score.fillna(0.5) + w_cost*fuel_cost_score.fillna(0.5) + w_ev*ev_score.fillna(0.5) + \
121
+ w_cargo*cargo_score.fillna(0.5) + w_perf*perf_mix.fillna(0.5)
122
+
123
+ df_out = df.copy()
124
+ df_out["Score"] = score.round(4)
125
+ show_cols = [c for c in [
126
+ COLS["make"], COLS["model"], "Year" if "Year" in df.columns else None,
127
+ COLS["fuel1"] if COLS["fuel1"] in df.columns else COLS["fuel_any"],
128
+ COLS["drive"], COLS["trans"],
129
+ COLS["mpg_city_f1"], COLS["mpg_hwy_f1"], COLS["mpg_comb_f1"],
130
+ COLS["annual_fuel_cost_f1"], COLS["ev_range_f2"],
131
+ COLS["cyl"], COLS["disp"],
132
+ "Score"
133
+ ] if (c and (c in df.columns)) or c=="Score"]
134
+
135
+ return df_out.sort_values("Score", ascending=False).head(10)[show_cols]
136
+
137
+ with gr.Blocks(title="诪诪诇讬抓 专讻讘讬诐") as demo:
138
+ gr.Markdown("# 诪诪诇讬抓 专讻讘讬诐 讞讻诐\n讛讗驻诇讬拽爪讬讛 诪转讗讬诪讛 讚讙诪讬诐 诇爪专讻讬诐 砖诇讱 注诇 讘住讬住 讚讗讟讛 砖诇 EPA.\n")
139
+
140
+ with gr.Row():
141
+ usage = gr.Radio(["注讬专", "讘讬谞注讬专讜谞讬", "诪注讜专讘"], value="诪注讜专讘", label="讗讜驻讬 砖讬诪讜砖")
142
+ daily_km = gr.Slider(0, 200, value=30, step=5, label="谞住讜注讛 讬讜诪讬转 诪诪讜爪注转 讘拽讬诇讜诪讟专讬诐")
143
+ budget_fuel = gr.Slider(0, 6000, value=3000, step=100, label="转拽爪讬讘 讚诇拽 讗讜 讞砖诪诇 砖谞转讬")
144
+
145
+ with gr.Row():
146
+ fuel_pref = gr.Dropdown(choices=FUEL_OPTS, value="No preference", label="注讚讬驻讜转 诇住讜讙 讚诇拽")
147
+ drive_pref = gr.Dropdown(choices=DRIVE_OPTS, value="No preference", label="讛谞注讛")
148
+ trans_pref = gr.Dropdown(choices=TRANS_OPTS, value="No preference", label="转讬讘转 讛讬诇讜讻讬诐")
149
+
150
+ with gr.Row():
151
+ cargo_need = gr.Slider(0, 800, value=0, step=20, label="谞驻讞 诪讟注谉 诪讬谞讬诪诇讬 专爪讜讬")
152
+ perf_pref = gr.Slider(0, 1, value=0.4, step=0.05, label="注讚讬驻讜转 0 讞住讻讜谉 1 讘讬爪讜注讬诐")
153
+ seats_min = gr.Slider(2, 8, value=4, step=1, label="诪讜砖讘讬诐 诪讬谞讬诪讜诐")
154
+
155
+ btn = gr.Button("诪爪讗 专讻讘讬诐")
156
+ out = gr.Dataframe(interactive=False, wrap=True, label="讛转讗诪讜转 诪讜诪诇爪讜转 . 讟讜驻 10")
157
+
158
+ btn.click(fn=recommend,
159
+ inputs=[budget_fuel, usage, daily_km, seats_min, fuel_pref, drive_pref, trans_pref, cargo_need, perf_pref],
160
+ outputs=out)
161
+
162
+ demo.queue().launch()
requirements-2.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio
2
+ pandas
3
+ numpy