Finding — Round-wise counting drama: AC 56's seven lead changes
Out of 234 ACs, 121 had zero lead changes during counting (decided from round 1). 18 ACs had 4 or more lead changes — genuine nail-biters. AC 56 (Krishnagiri district) had 7 lead changes across 23 rounds.
Distribution of lead changes across rounds
| Lead changes during counting | # ACs |
|---|---|
| 0 (decided from round 1) | 121 |
| 1 | 53 |
| 2 | 26 |
| 3 | 16 |
| 4 | 9 |
| 5 | 5 |
| 6 | 3 |
| 7 | 1 (AC 56) |
About 52% of ACs were decisive from the first counting round — the winner led every single round. The remaining 113 ACs had varying degrees of drama. 18 ACs (7.7% of TN) saw the lead change 4+ times during counting — these are the genuine nail-biters where postal-vote opening, late-counted booth batches, and round-specific demographics could have flipped the result.
The 10 most volatile ACs (most lead changes)
| AC | Lead changes |
|---|---|
| 56 (Thalli) | 7 |
| 75 | 6 |
| 190 | 6 |
| 210 | 6 |
| 35 | 5 |
| 72 | 5 |
| 76 | 5 |
| 134 | 5 |
| 223 | 5 |
| 85 | 4 |
AC 56 — Thalli
Krishnagiri district. 7 lead changes across counting. The winner emerged in the late rounds after multiple swings. Worth a separate case study — this is the kind of seat where counting-day cliffhanger commentary actually wrote itself.
What "lead changes" actually means
ECI publishes per-round vote totals per candidate. For each AC, at the end of each round, we compute who's currently leading (cumulative votes received). A lead change is when that leader differs from the previous round's leader.
# Per round, find leader
leader_per_round = rounds.sort('total', descending=True).group_by(['ac_no', 'round_no']).first()
# Count when leader[round_N] != leader[round_N-1]
lead_changes_per_ac = leader_per_round.with_columns(
pl.col('leader').shift(1).over('ac_no').alias('prev_leader')
).filter(pl.col('prev_leader').is_not_null()).group_by('ac_no').agg(
(pl.col('leader') != pl.col('prev_leader')).sum().alias('lead_changes')
)Why this is interesting
Lead changes correlate with both competitiveness (close races flip more) and geographic counting order (specific booths often counted in specific rounds — if rural booths come early and urban late, you'll see late swings). Without booth-level data we can't fully decompose this, but:
- Of the 18 ACs with 4+ lead changes, most are also in the closest-margin set (sub-5K margin races).
- AC 56's 7-change drama is genuinely unusual — most close races still see 3-4 changes, not 7. Likely reflects very heterogeneous booth-level composition.
- 121 ACs with zero lead changes are the "called the moment counting started" set — usually big-margin wins where the winner was ahead from booth 1.
Cross-validation
Yashwant Deshmukh on counting-day commentary in TN: "Several seats kept swinging until the last round." This data quantifies that statement: 113 of 234 (48%) saw at least one lead change; 18 saw 4+.
What we can't see without booth data
- Which booths were counted in which round — postal-vote batches usually come first, then booth-batches in geographic order.
- Whether late-counting urban booths in specific ACs systematically helped TVK (the "urban came in late" thesis).
- Per-booth volatility within an AC.
That's Path B territory — booth-level OCR, which we haven't run.
Cross-check
Source: s3://tnelection2026/results/curated/year=2026/ac=*/round_votes.parquet (per-AC per-round cumulative totals). Computation in pipelines/deep_dive.py.