
Kitchen Inflation PBS price PDFs · 163 weeks, 17 cities
A pipeline that reads the Pakistan Bureau of Statistics' weekly price PDFs: 51 essentials, 17 cities, 141,321 prices. Pick an item to see what it costs around the country, then read what the data shows.
Introduction
The Pakistan Bureau of Statistics publishes weekly prices for 51 essentials in 17 cities, but only as PDFs, with hand-typed file names and layouts that shift between years.
Project
An automated pipeline that finds every weekly report, parses and validates the prices, loads them into DuckDB, and republishes a dashboard and this case study every Saturday on GitHub Actions.
Challenge
Ordinary text extraction interleaves the table cells into nonsense. Rebuilding cells from the PDFs' own tags recovers the tables exactly: 0 of 156,060 cells differ from PBS's Excel files where both exist.
My role
Solo project: discovery crawler, PDF parser, 11 validation checks, DuckDB views, charts and write-up. Python, pdfplumber, DuckDB and GitHub Actions.
Links
Atta
This week, city by city
Show this item as a table
The same bag of atta, 38% apart
In the week ended 5 November 2026, a 20 kg bag of atta cost Rs 3,340 in Hyderabad and Rs 2,418 in Multan: Rs 922 more for the same staple, in the same week. The split follows provincial lines. Punjab, where most of the country's wheat is grown, had the cheapest atta of the five regions in 100% of the last 52 weeks.
The gap is new. In the archive's first year the other four regions paid on average 3% more than Punjab for atta; over the last 52 weeks they paid 20% more. This matters most to poorer households. Atta is 6.1% of the lowest-spending fifth's basket in PBS's index, against 4.0% for households overall.
How much more atta costs outside Punjab
Average price in Sindh, KP, Balochistan and Islamabad compared with Punjab, %, weekly. Use the explorer above for city prices.
Islamabad pays the most, almost every week
To compare cities fairly I price the same basket everywhere: the 29 grocery items, using only those collected in all 17 cities that week, weighted by what households spend on each. On that basket Islamabad costs 11.3% more than the 17-city average and was the dearest city in 93% of weeks. Sargodha is cheapest, 9.1% below average.
Even Rawalpindi, the twin city next door, is 3.1 points cheaper than Islamabad in 96% of weeks. The premium is fresh food, not packaged goods: in Islamabad, bananas cost 62% more than the national mean, potatoes 33% and tomatoes 31%.
Same basket, by city
Average over all weeks. 100 = 17-city average.
Where Islamabad's premium comes from
Average price above the 17-city mean, by grocery item.
One price everywhere, or anything goes
Branded, packaged goods sell at close to one national price: across cities, cooking oil, ghee and packet tea stay within 8% of each other. Fresh produce does not. On a typical week the dearest city paid 2.5× the cheapest for bananas and 2.1× for tomatoes. Any city comparison is mostly a comparison of produce prices.
How far apart cities are, by grocery item
Dearest city's price divided by the cheapest's, typical week. 1× = the same price everywhere.
Prices rose least for the poorest households
PBS also publishes the index separately for five consumption groups, from the lowest-spending fifth of households (Q1) to the highest (Q5). Since July 2023, Q1's index rose 35.8%, the least of the five. Q5's rose 43.0%, and Q3 rose most, 47.3%.
It isn't steady. The year-on-year gap between the poorest and richest ran from −6.6 to +4.0 points, and the poorest faced the higher rate in only 27% of weeks. The reason is what each basket holds. Petrol is 1.5% of the poorest basket but 6.7% of the combined one, so fuel rises land harder on better-off homes. Breaking PBS's published year-on-year figures into item contributions shows petrol, lowest-slab electricity and lowest-slab gas pulling the poorest households' inflation below average, and firewood, onions and atta pushing it above.
Price index by household group, July 2023 = 100
PBS Sensitive Price Indicator, weekly.
What opens the gap
Average contribution to the poorest group's YoY inflation minus the overall index's, percentage points.
Meat and milk got dearer; staples got cheaper
Comparing average prices in the archive's first year (July 2023 to June 2024) with the latest 52 weeks: beef +44%, powdered milk +40%, mutton +30%. Over the same period atta changed −6%, basmati rice −3%, masoor dal −17% and potatoes −43%. Year-long averages, not single weeks, so a season can't pass for a trend. It fits the income story: a richer diet leans on exactly the things that rose.
Change in average price, first year vs latest 52 weeks
Grocery items; the seven biggest rises and seven biggest falls.
The tomato rollercoaster
Tomatoes are the most volatile item in the basket. Their national average price moves 13.4% in a typical week; for onions it's 4.5%, for atta 0.7%. The cheapest week was Rs 45 a kilo on 15 May 2025. The dearest was Rs 350 on 23 July 2026, 7.8 times as much.
Tomatoes, national average price per kg
Rupees, weekly. Gaps are weeks missing from the PBS archive.
Ramadan lifts one price reliably: bananas
For each Ramadan I compare prices in the fasting weeks with the four weeks before, then subtract the item's typical change over the same stretch in other months. Bananas rose clearly every time: +41 / +46 / +49 points above normal in 2024, 2025 and 2026. 11 of 29 grocery items never moved beyond their normal monthly swing.
Some items swing both ways. Potatoes went +19 / −11 / −24 points over the same three Ramadans. Every Ramadan so far has fallen in late winter or spring, so for seasonal produce the data can't yet separate Ramadan from the harvest. That changes as Ramadan moves about eleven days earlier each year.
Bananas, national average price per dozen
Rupees, weekly. Shaded: Ramadan.
How it's built
PBS publishes each week's prices as PDFs, with file names typed by hand (SPI_AnnexUSCP_06072023.pdf, ANNEX202620USCP2002.05.2024.pdf, Annex.pdf) and layouts that shift between years. The pipeline runs every Saturday on GitHub Actions and rebuilds everything from the PDFs.
- FindCrawl the index pages and WordPress media API for report links. No guessed URLs.
- ParseExtract the city tables with pdfplumber; the week comes from inside each file.
- Validate11 checks, from table shape to unit changes. Errors stop publication.
- StoreClean tables in git, analysis views in DuckDB.
- PublishA dashboard and this page, regenerated from the data.
The hardest part was the tables. The description and unit cells overlap on the page, so ordinary text extraction interleaves them into nonsense. The PDFs turned out to be tagged, with every table cell its own marked object. Rebuilding cells from those tags recovers the table exactly.
Plain text extraction
2Rice Basmati Broken (Average Qualit1y )Kg 260.00 274.83 10Powdered Milk NIDO 390 gm PolybaEgach 1100.00
Cells rebuilt from the PDF's tags
| Item | Unit | Islamabad avg |
|---|---|---|
| Rice Basmati Broken (Average Quality) | 1 Kg | 274.83 |
| Powdered Milk NIDO 390 gm Polybag | Each | 1,100.00 |
What the checks caught. Validation doesn't fix the data quietly; it flags anything odd for a person to look at:
- Larkana tomatoes listed at about a quarter of every other city's price for five straight weeks in 2025, consistent with a price per 250 g typed in as per kilo.
- Chilli powder nearly doubling overnight in July 2023 with the pack description unchanged: a price rise or a silent pack-size change.
- PBS restating a previous week's index for the poorest group by 2.04 points in November 2025, which my year-on-year breakdown accounts for explicitly.
- 32 weeks that exist nowhere on the PBS site, including a seven-week hole in late 2024. Charts show them as gaps rather than joining across them.
What this can't tell you
These are average prices in the markets PBS samples: 50 markets across 17 cities, and in 7 smaller cities the minimum and maximum prices are almost always identical, which suggests a single market. It is a price index, not a cost of living, so rent, transport and wages are outside it. The income groups and their weights are PBS's, fixed at 2015-16 spending patterns. The archive starts in July 2023. Every cleaning decision is written up in the methods note.