sony9316 commited on
Commit
e60baea
·
verified ·
1 Parent(s): d8667c2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -2
app.py CHANGED
@@ -12,8 +12,8 @@ warnings.filterwarnings('ignore')
12
 
13
  # ========== PAGE CONFIGURATION ==========
14
  st.set_page_config(
15
- page_title="Getaround Delay Analysis",
16
- page_icon="🚗",
17
  layout="wide",
18
  initial_sidebar_state="expanded"
19
  )
@@ -292,6 +292,111 @@ if selected == "Overview & Problems":
292
  </div>
293
  """, unsafe_allow_html=True)
294
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
  # Visual analysis
296
  st.markdown('<div class="section-header">Delay Patterns</div>', unsafe_allow_html=True)
297
 
 
12
 
13
  # ========== PAGE CONFIGURATION ==========
14
  st.set_page_config(
15
+ page_title="Car Rental Delay Analysis",
16
+ #page_icon="🚗",
17
  layout="wide",
18
  initial_sidebar_state="expanded"
19
  )
 
292
  </div>
293
  """, unsafe_allow_html=True)
294
 
295
+ # Direct answer to PM's questions
296
+ st.markdown('<div class="section-header">How Often Are Drivers Late & Impact on Next Driver</div>', unsafe_allow_html=True)
297
+
298
+ # Calculate late return frequency and impact
299
+ df_late_analysis = df[df["has_previous_rental"]].copy()
300
+
301
+ # Join with previous rental delay data
302
+ prev_rental_data = df[["rental_id", "delay_at_checkout_in_minutes"]].rename(
303
+ columns={"rental_id": "previous_ended_rental_id",
304
+ "delay_at_checkout_in_minutes": "previous_delay"}
305
+ )
306
+ df_late_analysis = df_late_analysis.merge(prev_rental_data, on="previous_ended_rental_id", how="left")
307
+
308
+ # Calculate late return frequency
309
+ df_late_analysis["previous_delay_clean"] = df_late_analysis["previous_delay"].clip(-720, 720)
310
+ df_late_analysis["previous_was_late"] = (
311
+ df_late_analysis["previous_delay"].notnull() &
312
+ (df_late_analysis["previous_delay_clean"] > 0)
313
+ )
314
+
315
+ # Calculate impact on next driver
316
+ df_late_analysis["causes_problem"] = (
317
+ df_late_analysis["previous_delay"].notnull() &
318
+ (df_late_analysis["previous_delay_clean"] > df_late_analysis["time_delta_with_previous_rental_in_minutes"])
319
+ )
320
+ df_late_analysis["wait_time"] = np.maximum(
321
+ 0,
322
+ df_late_analysis["previous_delay_clean"] - df_late_analysis["time_delta_with_previous_rental_in_minutes"]
323
+ ).fillna(0)
324
+
325
+ late_returns = df_late_analysis[df_late_analysis["previous_was_late"]]
326
+ impacted_next_drivers = df_late_analysis[df_late_analysis["causes_problem"]]
327
+
328
+ col1, col2 = st.columns(2)
329
+
330
+ with col1:
331
+ st.markdown("#### Late Return Frequency")
332
+ total_with_delay_data = df_late_analysis[df_late_analysis["previous_delay"].notnull()]
333
+ late_frequency = (len(late_returns) / len(total_with_delay_data)) * 100 if len(total_with_delay_data) > 0 else 0
334
+
335
+ st.metric("Late Returns", f"{len(late_returns):,}")
336
+ st.metric("Late Return Rate", f"{late_frequency:.1f}%",
337
+ help="Percentage of returns that are late (delay > 0 minutes)")
338
+
339
+ # Late return severity
340
+ if len(late_returns) > 0:
341
+ avg_late_delay = late_returns["previous_delay_clean"].mean()
342
+ st.metric("Average Late Delay", f"{avg_late_delay:.1f} min")
343
+
344
+ with col2:
345
+ st.markdown("#### Impact on Next Driver")
346
+ impact_rate = (len(impacted_next_drivers) / len(df_late_analysis)) * 100 if len(df_late_analysis) > 0 else 0
347
+
348
+ st.metric("Next Drivers Impacted", f"{len(impacted_next_drivers):,}")
349
+ st.metric("Impact Rate", f"{impact_rate:.1f}%",
350
+ help="Percentage of consecutive rentals where late return causes waiting")
351
+
352
+ if len(impacted_next_drivers) > 0:
353
+ avg_wait = impacted_next_drivers["wait_time"].mean()
354
+ st.metric("Average Wait Time", f"{avg_wait:.1f} min",
355
+ help="Average additional wait time when impacted")
356
+
357
+ # Visual analysis of the relationship
358
+ col1, col2 = st.columns(2)
359
+
360
+ with col1:
361
+ # Late return distribution
362
+ if len(late_returns) > 0:
363
+ late_delays = late_returns["previous_delay_clean"]
364
+ late_filtered = late_delays[late_delays <= 300] # Cap at 5 hours for visualization
365
+
366
+ fig_late = px.histogram(
367
+ late_filtered,
368
+ nbins=20,
369
+ title="Distribution of Late Return Delays",
370
+ labels={"value": "Delay (minutes)", "count": "Number of Late Returns"}
371
+ )
372
+ st.plotly_chart(fig_late, use_container_width=True)
373
+
374
+ with col2:
375
+ # Wait time impact distribution
376
+ if len(impacted_next_drivers) > 0:
377
+ wait_times = impacted_next_drivers[impacted_next_drivers["wait_time"] > 0]["wait_time"]
378
+
379
+ fig_wait = px.histogram(
380
+ wait_times,
381
+ nbins=20,
382
+ title="Wait Time Distribution for Impacted Next Drivers",
383
+ labels={"value": "Wait Time (minutes)", "count": "Number of Impacted Drivers"}
384
+ )
385
+ st.plotly_chart(fig_wait, use_container_width=True)
386
+
387
+ # Key insight summary
388
+ late_to_impact_ratio = (len(impacted_next_drivers) / len(late_returns)) * 100 if len(late_returns) > 0 else 0
389
+
390
+ st.markdown(f"""
391
+ <div class="insight-box">
392
+ <strong>Key Insights:</strong><br>
393
+ • <strong>{late_frequency:.1f}%</strong> of returns are late (drivers return after scheduled time)<br>
394
+ • <strong>{impact_rate:.1f}%</strong> of consecutive rentals are negatively impacted by previous late returns<br>
395
+ • <strong>{late_to_impact_ratio:.1f}%</strong> of late returns actually cause problems for the next driver<br>
396
+ • When problems occur, next drivers wait an average of <strong>{avg_wait:.1f} minutes</strong>
397
+ </div>
398
+ """, unsafe_allow_html=True)
399
+
400
  # Visual analysis
401
  st.markdown('<div class="section-header">Delay Patterns</div>', unsafe_allow_html=True)
402