Pressing
Summary
Per-team-season aggregates of where each team wins the ball back. The
team style profiling on /analysis/style already exposes a z-scored
"pressing" dimension, but a z-score hides the denominator and conflates
two different questions: where did you win it back vs how often. The
pressing page surfaces both: the share split (att / mid / def of total
recoveries) plus per-match volume.
The single-axis press_height_index = (att − def) / total lives in
[−1, 1]. Positive = recoveries skew the attacking third (active high
press), negative = recoveries skew the defensive third (deeper block).
Most teams are negative because the league-wide split sits around
10% / 45% / 45%; the question is who is less negative.
The feature lives at /analysis/pressing and is also exposed on the
team quadrant page (Pressing Height, Press vs Possession).
Inputs
| Stored column | SDP key | Meaning |
|---|---|---|
poss_won_att_3rd |
possWonAtt3rd |
Possessions won in the attacking third. |
poss_won_mid_3rd |
possWonMid3rd |
Possessions won in the middle third. |
poss_won_def_3rd |
possWonDef3rd |
Possessions won in the defensive third. |
poss_won_total |
(sum of the three) | Total recoveries. Stored to make the share denominators stable on read. |
press_height_index |
derived | (att − def) / total, precomputed so the same value is used by the page and the quadrant catalog. |
Sums are over regular-season team-matches only
(matches.is_playoff = 0), matching the default scope of every other
team-season aggregate (form, splits, xPts, SQI, set-pieces).
All three keys are present in every season the feed covers (2019-2025+), so there is no per-season metric availability gap.
Derived rates
Computed server-side on read from the stored counters. None when the
denominator is zero.
- Att 3rd share =
poss_won_att_3rd / poss_won_total - Mid 3rd share =
poss_won_mid_3rd / poss_won_total - Def 3rd share =
poss_won_def_3rd / poss_won_total - Recoveries / match =
poss_won_total / matches - Att 3rd / match =
poss_won_att_3rd / matches
Per-match volume is paired with share because they answer different questions. Share answers "where on the pitch", which is mostly tactical. Per-match volume answers "how often", which is partly tactical (aggressive teams force more turnovers) and partly a function of how often the team loses the ball in the first place.
Pressing height index
A single composite axis for the team quadrant page:
press_height_index = (poss_won_att_3rd − poss_won_def_3rd) / poss_won_total
Range [−1, 1]:
- +1 = every recovery in the attacking third (max press).
- −1 = every recovery in the defensive third (deepest block).
- 0 = balanced (or all middle-third).
This is precomputed in compute_pressing.py so the same number powers
both the dedicated page and advanced_metrics.py. No z-scoring
involved — it's a pure, per-team-season ratio that's directly comparable
across seasons.
Data caveats
- Tempo confound on per-match counts. A team that loses the ball more often will recover it more often in absolute terms. Share metrics cancel this out (they sum to 1 within a team-season); per- match counts don't. Read share as the primary signal for tactical intent and per-match as the secondary signal for activity.
- Pitch-thirds, not pitch-zones. The feed only emits the three thirds. There's no way to split a recovery in the attacking third by flank or central, or by distance to goal.
- 2020 Island Games had 7-11 matches per team in a neutral bubble without travel, rest variance, or crowds. Rows from 2020 are flagged on the page and should not be compared directly to other seasons.
- Recovery, not pressure. SDP's
possWonAtt3rdcounts where the ball was recovered, not where pressure was applied. A team that presses high but invites turnovers in deeper zones will look like a deep-block team on this metric. Pairing with PPDA on the quadrant page partially mitigates this — PPDA captures intensity, height captures location.
Why this isn't a model
Same reason as set-pieces: the data volume is small (~55 team-seasons),
and the underlying counts are large enough that simple ratios already
carry the signal. Z-scoring within season (as team_style does) hides
the denominator and forces the reader through one extra layer of
interpretation. This page sticks to raw counters + direct rates +
one bounded composite index.