The question
Compare the centre and spread of delivery durations across depots.
df Spread comparisonYour inputs
df
One row is a completed delivery. Durations include unknown values and a genuine long delivery; do not discard an observation merely because it is unusual.
Field meanings and units
delivery_id- Delivery identifier.
depot- Depot responsible for the delivery.
status- Recorded delivery state.
minutes- Elapsed duration in minutes; unknown is not zero.
weight_kg- Weight in kilograms.
date- Calendar date supplied as YYYY-MM-DD text unless the task states it is invalid.
delivery_id | depot | status | minutes | weight_kg | date |
|---|---|---|---|---|---|
| D001 | East | Delivered | 32 | 1.2 | 2026-04-01 |
| D002 | West | Delivered | 48 | 1.9 | 2026-04-01 |
| D003 | North | Delivered | 25 | 2.6 | 2026-04-02 |
| D004 | East | Delivered | None | 3.3 | 2026-04-02 |
| D005 | West | Delivered | 45 | 4 | 2026-04-03 |
View all 24 rows
delivery_id | depot | status | minutes | weight_kg | date |
|---|---|---|---|---|---|
| D001 | East | Delivered | 32 | 1.2 | 2026-04-01 |
| D002 | West | Delivered | 48 | 1.9 | 2026-04-01 |
| D003 | North | Delivered | 25 | 2.6 | 2026-04-02 |
| D004 | East | Delivered | None | 3.3 | 2026-04-02 |
| D005 | West | Delivered | 45 | 4 | 2026-04-03 |
| D006 | North | Delivered | 37 | 1.2 | 2026-04-03 |
| D007 | East | Delivered | 72 | 1.9 | 2026-04-04 |
| D008 | West | Delivered | 29 | 2.6 | 2026-04-04 |
| D009 | North | Delivered | bad | 3.3 | 2026-04-05 |
| D010 | East | Delivered | 49 | 4 | 2026-04-05 |
| D011 | West | Delivered | 26 | 1.2 | 2026-04-06 |
| D012 | North | Delivered | 62 | 1.9 | 2026-04-06 |
| D013 | East | Delivered | 46 | 2.6 | 2026-04-07 |
| D014 | West | Delivered | 38 | 3.3 | 2026-04-07 |
| D015 | North | Delivered | 73 | 4 | 2026-04-08 |
| D016 | East | Delivered | 30 | 1.2 | 2026-04-08 |
| D017 | West | Delivered | 34 | 1.9 | 2026-04-09 |
| D018 | North | Delivered | 50 | 2.6 | 2026-04-09 |
| D019 | East | Delivered | 27 | 3.3 | 2026-04-10 |
| D020 | West | Delivered | 63 | 4 | 2026-04-10 |
| D021 | North | Delivered | 47 | 1.2 | 2026-04-11 |
| D022 | East | Delivered | 180 | 1.9 | 2026-04-11 |
| D023 | West | Delivered | 74 | 2.6 | 2026-04-12 |
| D024 | North | Delivered | 31 | 3.3 | 2026-04-12 |
The editable setup in Your Python creates these inputs when you run it.
Compare the centre and spread of delivery durations across depots.
observationsDataFramefigFigureDeliverables
Make the outputs listed below. Use each name exactly as shown. Then choose Check answer.
Python name key
Teal outlines name table columns. Violet left rules name Python objects. Dotted rules mark syntax, functions and parameters. Use each name exactly as shown.
- Valid delivery measurementsOutput
observationsDataFrame- Create
observationswithdepotand parsedminutesfor known durations, keeping source order.
- Create
- FigureOutput
figFigure- Create
figcomparingdepotmedians, middle 50%, and 1.5-IQR whiskers, including outliers. - Put depots on the horizontal axis and
minuteson the vertical axis. - Add a meaningful title and labels
- Display the figure.
Identify Depot and Minutes on the appropriate axes; extra wording is welcome.
- Create
Data policy Keep all supplied source tables unchanged. Work on separate outputs.
Help Hints & explained solution
Choose the amount of help you need. Opening one hint does not reveal the others.
Hint 1 — Think
What could two groups with similar means still differ in?
Hint 2 — Tools
to_numeric(), dropna(), sns.boxplot() or Axes.boxplot()
Revisit: Convert numeric text · Drop missing rows · Box plot · Finish a chart properly
Hint 3 — Approach
Retain known numeric durations and compare each depot’s median, middle half and whiskers using the standard 1.5-IQR rule.
Explained solution
Add these lines below # Your work in the editor. The supplied input setup is already there.
work = df.copy()
work['minutes'] = pd.to_numeric(work.minutes, errors='coerce')
observations = work[['depot', 'minutes']].dropna()
fig, ax = plt.subplots()
sns.boxplot(
data=observations,
x='depot',
y='minutes',
ax=ax,
)
ax.set(title='Delivery duration spread', xlabel='Depot', ylabel='Minutes')
fig.tight_layout()
plt.show()View supplied setup
This code is already at the top of the editor.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Supplied input: df (24 rows)
df = pd.DataFrame(
[
('D001', 'East', 'Delivered', 32, 1.2, '2026-04-01'),
('D002', 'West', 'Delivered', 48, 1.9, '2026-04-01'),
('D003', 'North', 'Delivered', 25, 2.6, '2026-04-02'),
('D004', 'East', 'Delivered', None, 3.3, '2026-04-02'),
('D005', 'West', 'Delivered', 45, 4, '2026-04-03'),
('D006', 'North', 'Delivered', 37, 1.2, '2026-04-03'),
('D007', 'East', 'Delivered', 72, 1.9, '2026-04-04'),
('D008', 'West', 'Delivered', 29, 2.6, '2026-04-04'),
('D009', 'North', 'Delivered', 'bad', 3.3, '2026-04-05'),
('D010', 'East', 'Delivered', 49, 4, '2026-04-05'),
('D011', 'West', 'Delivered', 26, 1.2, '2026-04-06'),
('D012', 'North', 'Delivered', 62, 1.9, '2026-04-06'),
('D013', 'East', 'Delivered', 46, 2.6, '2026-04-07'),
('D014', 'West', 'Delivered', 38, 3.3, '2026-04-07'),
('D015', 'North', 'Delivered', 73, 4, '2026-04-08'),
('D016', 'East', 'Delivered', 30, 1.2, '2026-04-08'),
('D017', 'West', 'Delivered', 34, 1.9, '2026-04-09'),
('D018', 'North', 'Delivered', 50, 2.6, '2026-04-09'),
('D019', 'East', 'Delivered', 27, 3.3, '2026-04-10'),
('D020', 'West', 'Delivered', 63, 4, '2026-04-10'),
('D021', 'North', 'Delivered', 47, 1.2, '2026-04-11'),
('D022', 'East', 'Delivered', 180, 1.9, '2026-04-11'),
('D023', 'West', 'Delivered', 74, 2.6, '2026-04-12'),
('D024', 'North', 'Delivered', 31, 3.3, '2026-04-12'),
],
columns=['delivery_id', 'depot', 'status', 'minutes', 'weight_kg', 'date'],
)Why these steps exist
- The middle half and whiskers describe spread that a single average hides.
- The long delivery remains visible as an outlier under the 1.5-IQR rule; unusual is not the same as invalid.
Another valid approach
Matplotlib or Seaborn box plots are accepted with the same group quartiles, 1.5-IQR whiskers and visible outliers.