Credit vs debit card usage by bank from RBI's monthly statistics
In this article (7 sections)
Related programme: the Data Analytics with Generative AI course (3–4 months; ₹90,000 (inclusive of GST) · EMI from ₹4,000/month).
RBI publishes a monthly file of card and acceptance statistics for every bank: how many cards are outstanding and how they are used. From it you can answer a question that product, risk and strategy teams in card businesses care about: which banks' cards are actually used, and how does usage differ between credit and debit cards? This project builds a clean bank-month table from those files and computes spend per card and transactions per card. It then presents the comparison with the caveats RBI's own file layout forces on you.
Finding the files
Go to RBI's Bank-wise ATM/POS/Card Statistics page. It lists one entry per month, each with an Excel file and a PDF. When we checked in September 2026, the latest was August 2026. Two quirks from the listing itself:
- Some months are marked "Revised". A revised file replaces the earlier one for that month. Keep both and record which you used.
- File names do not always match the month they are listed under. The November 2025 entry, for example, pointed to files named with "OCTOBER2025". Identify a file's month from its contents, not its name.
We could not download the Excel file with a script (the server returned a browser-check page), so we have not confirmed its column layout. Download it in a browser and read the header rows before writing any parser. Expect grouped headings, with several levels, and bank names grouped under bank categories.
Why a card business would care
Issuers watch "active" and "spend per card" more than raw cards issued, because a card in a drawer costs money and earns nothing. A clean comparison of credit and debit card usage across banks is a standard competitive-benchmarking task in fintech, bank strategy and payments consulting. It also shows you can build a reliable table from an awkward official spreadsheet, which is most of the real job.
Building the table
Once you have read the header, write a small mapping from the file's column positions to your own names. Record the file's exact wording beside each one. For this project you need, for each card type:
- cards outstanding at month end
- transaction volume and value in the channels the file reports, for example at POS terminals and online
Then:
- 1Flatten the multi-level header into names like
cc_outstanding,cc_pos_value,dc_pos_volume. - 2Drop group subtotal rows (for example a total for all public sector banks) from the bank-level table. Keep them separately to reconcile against.
- 3Normalise bank names, since mergers and renamings happen. Keep a mapping table with the effective month of each change.
- 4Record units from the file's header, such as numbers in actual units, lakh or millions, and value in rupees crore or lakh. Put them in the column names.
Code on synthetic bank rows
These rows are synthetic. The banks are placeholders, and the numbers are invented rather than taken from RBI's file.
import pandas as pd
raw = pd.DataFrame({
"bank_group": ["Public Sector Banks"] * 3 + ["Private Sector Banks"] * 3,
"bank": ["Bank P1", "Bank P2", "Public Sector Banks Total",
"Bank R1", "Bank R2", "Private Sector Banks Total"],
"cc_outstanding": [1_200_000, 300_000, 1_500_000, 9_000_000, 4_000_000, 13_000_000],
"cc_value_cr": [900.0, 150.0, 1_050.0, 14_000.0, 5_200.0, 19_200.0],
"dc_outstanding": [90_000_000, 40_000_000, 130_000_000, 30_000_000, 12_000_000, 42_000_000],
"dc_value_cr": [5_000.0, 1_800.0, 6_800.0, 3_500.0, 1_400.0, 4_900.0],
})
is_total = raw["bank"].str.endswith("Total")
banks, totals = raw[~is_total].copy(), raw[is_total].set_index("bank_group")
# Reconcile: bank rows must add up to each group's total row
summed = banks.groupby("bank_group")[["cc_outstanding", "cc_value_cr"]].sum()
diff = (summed - totals[["cc_outstanding", "cc_value_cr"]]).abs()
assert (diff < 1e-6).all().all(), diff
for card in ("cc", "dc"):
banks[f"{card}_spend_per_card_rs"] = (banks[f"{card}_value_cr"] * 1e7
/ banks[f"{card}_outstanding"]).round(0)
banks["credit_to_debit_spend_ratio"] = (banks["cc_spend_per_card_rs"]
/ banks["dc_spend_per_card_rs"]).round(1)
print(banks[["bank", "cc_spend_per_card_rs", "dc_spend_per_card_rs",
"credit_to_debit_spend_ratio"]].to_string(index=False))One crore is 10,000,000 rupees, hence the 1e7. If the file reports value in lakh, the factor is 1e5. Getting this wrong is the most common error with Indian official data, so assert the units you read from the header in a comment next to the calculation.
Analysis plan
- 1Build a bank-month table for twelve consecutive months, using revised files where they exist.
- 2Compute spend per card and transactions per card, monthly, for credit and debit cards.
- 3Rank banks with at least a minimum number of cards outstanding. Small banks produce unstable ratios.
- 4Compare bank groups: public, private, foreign and small finance banks, if the file groups them that way.
- 5Track change: which banks' spend per credit card rose fastest over the year?
What you deliver
- Bar chart: spend per credit card by bank, top 15, with the group shown by colour.
- Scatter: credit cards outstanding against spend per card. Large issuers are not always the most-used cards.
- Table: bank, group, cards, spend per card for credit and debit, and the ratio.
- README: page URL, months and download dates, revised-file choices, column mapping with the file's own wording, units, reconciliation results, limitations.
Among the limitations, say that spend per outstanding card is not spend per active card. RBI's file gives cards outstanding, not how many were used in the month.
Interview questions
- How did you confirm the units in each column?
- Why reconcile bank rows against group totals before analysing?
- What does "Revised" mean for your time series, and how did you handle it?
- A bank's spend per credit card doubled in a month. List three explanations before you believe it.
- Why is spend per outstanding card a biased measure of engagement?
For a modelling follow-up on the same RBI files, see the POS terminal growth project. Our Data Analyst programme spends real time on multi-row headers and unit checks, because they are where real reports go wrong.
Frequently asked questions
Where does RBI publish bank-wise card data?
RBI's website has a "Bank-wise ATM/POS/Card Statistics" page with a monthly file for each month, in Excel and PDF. Open the file and read its header rows carefully, because it has grouped, multi-level column headings.
Pankit Kumar has 10 years in Data Science & AI, building and shipping production systems in regulated pharma and clinical environments. He is a freelance trainer at Boston Institute of Analytics, AnalytixLabs and Scaler, and has taught this material to thousands of working professionals.
This article is part of our Data Analytics with Generative AI programme — 3–4 months. The full analyst stack — Excel, SQL, Power BI and Python pipelines — then a generative-AI layer you can prove is right.
Explore Data Analytics with Generative AI