All Data Labs

Operations analytics

Driver Supply and Demand Analysis

medium3–4 hours4 datasetsPremium

The whole brief is open to read. This lab's datasets come with Premium.

Company
Uber
Job positions
Data AnalystBusiness AnalystProduct Analyst
Topics
Marketplace operationsJoinsTime patternsBudget allocationSQL

The scenario

Uber: Measure the ride requests that go unmet for lack of a driver, and recommend where to spend the incentive budget.

Uber riders only get a ride if a driver is nearby when they open the app, and a request with no driver is a ride lost rather than delayed. Each city team has a weekly budget to pay drivers to be online at chosen places and times. You're an analyst supporting three city teams, who want that budget spent where it buys back the most rides.

Your task

Measure unmet demand by zone, day of the week and hour of the day across four weeks, estimate the fare it cost, and allocate a $60,000 weekly incentive budget.

Instructions

  1. 1Load the two hourly feeds and the zone and weather tables. Check the row counts against the number of zone-hours four weeks should contain before you join anything.
  2. 2Clean the data: handle repeated rows, and decide what to do about zone-hours one feed covers and the other does not. Explain your choice, because it changes the answer.
  3. 3Build a table at the level the city teams plan on, which is zone by day of the week by hour of the day. Save it as unmet_demand.csv with the columns zone_id, day_of_week, hour_of_day, requests, unmet_requests, unmet_rate and est_lost_fare_usd.
  4. 4Say which kinds of zone run short and when, and check whether the ranking changes when you order by share of requests unmet rather than by fare lost.
  5. 5Bring in the weather and measure what rain does to requests and to drivers online.
  6. 6Allocate the budget. A driver hour costs $9 and serves about 1.6 rides, and a zone-hour cannot give back more rides than went unmet there. Save incentive_plan.csv with the columns zone_id, day_of_week, hour_of_day, driver_hours_funded, incentive_cost_usd and est_rides_recovered.
  7. 7Write a short recommendation with the blocks you would fund first and what you expect back.

Datasets

All files come in one download.

ride_requests_hourly.csv

Rider demand per zone per hour, from September 1 to September 28, 2025.

12,060 rows · 9 columns · 568 KB

ColumnTypeDescription
zone_idtextThe pickup zone.
hour_startdatetimeStart of the hour, in local city time.
requestsintegerRiders who asked for a ride in that zone that hour.
completed_ridesintegerRequests that ended in a completed ride.
no_driver_requestsintegerRequests where no driver was available at all.
rider_canceledintegerRequests where a driver was found and the rider gave up before pickup.
avg_wait_secondsintegerAverage wait from request to pickup. Empty when no ride completed that hour.
avg_surge_multiplierdecimalAverage price multiplier applied that hour.
gross_fare_usddecimalTotal fare from the completed rides.
Preview the first 5 rows
zone_idhour_startrequestscompleted_ridesno_driver_requestsrider_canceledavg_wait_secondsavg_surge_multipliergross_fare_usd
SF012025-09-01 00:00:0099001651185.23
SF012025-09-01 01:00:0066001801109.59
SF012025-09-01 02:00:005500136189.94
SF012025-09-01 03:00:003300131160.29
SF012025-09-01 04:00:00330065161.22

driver_supply_hourly.csv

Driver availability per zone per hour over the same four weeks, recorded by a separate system.

11,850 rows · 4 columns · 370 KB

ColumnTypeDescription
zone_idtextThe zone the driver was available in.
hour_startdatetimeStart of the hour, in local city time.
drivers_onlineintegerDrivers who were online in the zone at some point that hour.
driver_hoursdecimalDriver hours available in the zone that hour.
Preview the first 5 rows
zone_idhour_startdrivers_onlinedriver_hours
SF012025-09-01 00:00:0076.7
SF012025-09-01 01:00:0054.7
SF012025-09-01 02:00:0044
SF012025-09-01 03:00:0022.3
SF012025-09-01 04:00:0033.3

zones.csv

The eighteen pickup zones across three cities.

18 rows · 4 columns · 1 KB

ColumnTypeDescription
zone_idtextUnique ID of the zone.
zone_nametextName the city team uses for the zone.
citytextCity the zone belongs to.
zone_typetextdowntown, nightlife, airport, residential or suburban.
Preview the first 5 rows
zone_idzone_namecityzone_type
SF01Financial DistrictSan Franciscodowntown
SF02Mission DistrictSan Francisconightlife
SF03SoMaSan Francisconightlife
SF04SFO TerminalsSan Franciscoairport
SF05SunsetSan Franciscoresidential

city_weather.csv

Hourly weather for each city over the same four weeks.

2,016 rows · 4 columns · 71 KB

ColumnTypeDescription
citytextThe city.
hour_startdatetimeStart of the hour, in local city time.
precipitation_mmdecimalRain in the hour, in millimeters. Zero when it was dry.
temperature_cdecimalTemperature in degrees Celsius.
Preview the first 5 rows
cityhour_startprecipitation_mmtemperature_c
San Francisco2025-09-01 00:00:00016.8
San Francisco2025-09-01 01:00:00015.5
San Francisco2025-09-01 02:00:00016.5
San Francisco2025-09-01 03:00:00013.5
San Francisco2025-09-01 04:00:00017.2

Hints

Keeping every demand row when you bring availability in leaves the gaps visible. Dropping them hides the hours you most need to look at, and reading them as no drivers invents a shortage.

merged = requests.merge(supply, on=["zone_id", "hour_start"], how="left")
merged["driver_hours"].isna().sum()

The budget runs out long before the shortage does, so what matters is what each block gives back per dollar rather than which blocks are busiest.

Deliverable

A public GitHub repo with your analysis (a notebook, scripts or SQL), unmet_demand.csv and incentive_plan.csv, and a README with your data checks, the patterns you found and the reasoning behind the budget.

When you're done, post your repo in the Solutions tab to share it with other learners.

What grading checks

Use this checklist to review your own work before you post and share it.

  • Submitted GitHub repo is public and reachable.
  • Repo contains at least one notebook, script or SQL file.
  • unmet_demand.csv has a row for every zone, day of the week and hour, with counts matching the expected values.
  • incentive_plan.csv stays inside the $60,000 weekly budget and claims no more recovered rides than went unmet in each block.
  • The zone-hours one feed covers and the other does not are found and handled, with the choice explained rather than read as no drivers.
  • The write-up names the zone types and times that run short, and notes that the two ways of ranking disagree.
  • Rain is measured against both requests and drivers online, and the allocation is justified by what each block gives back per dollar.