📍 Recipe: Shot Accuracy per Team#
This example shows how to calculate shot accuracy - the percentage of shots that were on target - for each team in a match.
🧰 What You’ll Learn#
How to access StatsBomb data using
Flow.statsbombmethodsHow to filter for shots
How to define custom group-level aggregations
How to compute derived metrics like accuracy %
Imports#
[1]:
from penaltyblog.matchflow import Flow, where_equals
Load the Data#
[2]:
# Load events for a StatsBomb match
match_id = 22912 # Champions League Final 2018/2019
flow = Flow.statsbomb.events(match_id)
Define our Custom Aggregation Function#
[3]:
def shot_accuracy(records):
total = 0
on_target = 0
for r in records:
total += 1
if r.get("outcome") in ("Goal", "Saved"):
on_target += 1
return round((on_target / total) * 100, 1) if total else 0.0
Calculate Shot Accuracy#
[4]:
(
flow.filter(where_equals("type.name", "Shot"))
.select("team.name", "shot.outcome.name")
.rename(**{"team.name": "team", "shot.outcome.name": "outcome"})
.group_by("team")
.summary(
{
"total_shots": "count",
"accuracy_pct": shot_accuracy,
}
)
.sort_by("accuracy_pct", ascending=False)
.assign(accuracy_pct=lambda r: round(r["accuracy_pct"], 1))
.show()
)
/Users/martin/repos/penaltyblog/venv/lib/python3.13/site-packages/statsbombpy/api_client.py:21: NoAuthWarning: credentials were not supplied. open data access only
warnings.warn(
| accuracy_pct | team | total_shots |
|----------------|-------------------|---------------|
| 50 | Tottenham Hotspur | 16 |
| 21.4 | Liverpool | 14 |