Reading CSV Files (read_csv)
Load a CSV file into a DataFrame with pd.read_csv — file paths, simulating files with io.StringIO, and the first four parameters: sep, header, names and skiprows.
Real cricket data never starts life inside your Python code. The IPL ball-by-ball dataset, the Orange Cap table, a season's match results — they all arrive as files, and the most common file of all is the CSV (Comma-Separated Values). A CSV is just plain text: the first line usually holds the column names, and every following line is one row, with values separated by commas.
text
player,team,matches,runs,average
Virat Kohli,RCB,15,741,61.75
Ruturaj Gaikwad,CSK,14,583,53.0pd.read_csv() reads that text, splits every line on the separator, guesses a data type for each column and hands you back a ready-to-use DataFrame. It is the single most-used function in all of pandas — almost every analysis begins with it.
Definition
pd.read_csv()is the pandas function that reads delimited text data (a CSV file, a URL, or any file-like object) and returns it as a DataFrame, automatically detecting column names from the header row and inferring a data type for every column.
- Delimited text — values separated by a fixed character. Usually a comma, but semicolons (
;), tabs and pipes (|) are also common. Thesepparameter tells pandas which one. - File-like object — anything with a
.read()method. That is why we can hand it anio.StringIO(a string pretending to be a file) — perfect for the browser playground, which has no real files. - Header row — by default line 1 becomes the column names (
header=0). - Infers a data type — a column of whole numbers becomes
int64, decimals becomefloat64, and text becomes the newstrdtype in pandas 3.
Syntax
python
pd.read_csv(filepath_or_buffer, sep=",", header="infer", names=None,
index_col=None, usecols=None, dtype=None, parse_dates=None,
na_values=None, nrows=None, skiprows=None, encoding=None)This topic covers the "shape of the file" parameters. The next topic covers the rest.
| Parameter | Meaning | Default |
|---|---|---|
filepath_or_buffer | path to the file ("data/ipl.csv"), a URL, or a file-like object such as io.StringIO | required |
sep | the character that separates values (",", ";", "\t", "|") | "," |
header | row number to use as column names, or None if the file has no header | "infer" (= row 0) |
names | list of column names to use instead of (or when there is no) header row | None |
skiprows | number of lines to skip at the top, or a list of line numbers to skip | None |
Reading a real file — three ways to write a Windows path
In Munna's notebooks the file sits on the Desktop. A Windows path contains backslashes, and in Python \ starts an escape sequence (\n, \t…), so write the path in one of these three safe forms:
python
df = pd.read_csv(r"C:\Users\Admin\Desktop\data\ipl_matches.csv") # 1. raw string (r"...")
df = pd.read_csv("C:\\Users\\Admin\\Desktop\\data\\ipl_matches.csv") # 2. double backslashes
df = pd.read_csv("C:/Users/Admin/Desktop/data/ipl_matches.csv") # 3. forward slashesAll three work. A URL works too — pd.read_csv("https://.../matches.csv") downloads and reads the file in one step (for GitHub, use the raw file link).
Simulating a file with io.StringIO
The browser playground has no Desktop and no internet, so in these notes we wrap CSV text in io.StringIO. To read_csv, it looks exactly like an open file:
python
import pandas as pd
import io
csv_text = """player,team,matches,runs,average
Virat Kohli,RCB,15,741,61.75
Ruturaj Gaikwad,CSK,14,583,53.0
Riyan Parag,RR,16,573,52.09
Travis Head,SRH,15,567,40.5
Sanju Samson,RR,16,531,48.27
"""
df = pd.read_csv(io.StringIO(csv_text))
print(df)
print(df.dtypes)text
player team matches runs average
0 Virat Kohli RCB 15 741 61.75
1 Ruturaj Gaikwad CSK 14 583 53.00
2 Riyan Parag RR 16 573 52.09
3 Travis Head SRH 15 567 40.50
4 Sanju Samson RR 16 531 48.27
player str
team str
matches int64
runs int64
average float64
dtype: objectHow it works: pandas read the first line as column names, created a default RangeIndex (0, 1, 2…) for the rows, and guessed the types: matches and runs hold whole numbers → int64; average has decimals → float64; names and teams are text → str.
Note (pandas 3): text columns now show the dtype
str. In pandas 2 (and in most older tutorials) the same columns showedobject. Also,type(df)now prints<class 'pandas.DataFrame'>instead ofpandas.core.frame.DataFrame.
Example — a different separator (sep)
Many European and Excel-exported files use a semicolon. If you forget sep, pandas treats every whole line as one value:
python
semi = """player;team;runs
Virat Kohli;RCB;741
Riyan Parag;RR;573
Travis Head;SRH;567
"""
print(pd.read_csv(io.StringIO(semi))) # wrong: default sep=","
print(pd.read_csv(io.StringIO(semi), sep=";")) # righttext
player;team;runs
0 Virat Kohli;RCB;741
1 Riyan Parag;RR;573
2 Travis Head;SRH;567
player team runs
0 Virat Kohli RCB 741
1 Riyan Parag RR 573
2 Travis Head SRH 567How it works: the first result has shape (3, 1) — a single column called player;team;runs. That "one giant column" is the classic sign of a wrong separator. For tab-separated files use sep="\t" (or the shortcut pd.read_table(), whose default separator is a tab).
Example — files without a header (header=None, names)
Some exported files contain only data rows. By default pandas would wrongly promote the first player to column names:
python
nohead = """Virat Kohli,RCB,741
Riyan Parag,RR,573
Travis Head,SRH,567
"""
print(pd.read_csv(io.StringIO(nohead))) # first row eaten as header!
print(pd.read_csv(io.StringIO(nohead), header=None)) # numbered columns 0, 1, 2
print(pd.read_csv(io.StringIO(nohead), header=None,
names=["player", "team", "runs"])) # our own namestext
Virat Kohli RCB 741
0 Riyan Parag RR 573
1 Travis Head SRH 567
0 1 2
0 Virat Kohli RCB 741
1 Riyan Parag RR 573
2 Travis Head SRH 567
player team runs
0 Virat Kohli RCB 741
1 Riyan Parag RR 573
2 Travis Head SRH 567How it works: header=None says "there is no header line — every line is data", so pandas numbers the columns 0, 1, 2. Adding names=[...] gives them proper labels. You can also use names together with header=0 to replace an existing header with your own names.
Example — junk lines at the top (header=1 / skiprows)
Reports often start with a title line before the real header:
python
title = """IPL 2024 Orange Cap Table
player,team,runs
Virat Kohli,RCB,741
Riyan Parag,RR,573
"""
print(pd.read_csv(io.StringIO(title), header=1)) # header is on line 1 (0-based)
print(pd.read_csv(io.StringIO(title), skiprows=1)) # or: skip 1 line, then read normallytext
player team runs
0 Virat Kohli RCB 741
1 Riyan Parag RR 573
player team runs
0 Virat Kohli RCB 741
1 Riyan Parag RR 573How it works: both give the same result. header=1 means "line number 1 (counting from 0) is the header and everything above it is thrown away". skiprows=1 removes the first line first, then reads the rest with the default header.
The family of read functions
| Function | Reads | Needs extra library? |
|---|---|---|
pd.read_csv() | CSV / any delimited text | no |
pd.read_table() | tab-separated text (sep="\t" by default) | no |
pd.read_json() | JSON text / files | no |
pd.read_excel() | .xlsx / .xls workbooks | yes — openpyxl (xlsx) |
pd.read_html() | every <table> on a web page | yes — lxml or bs4 + html5lib |
pd.read_sql() | result of an SQL query | a database connection |
pd.read_clipboard() | whatever table you copied (e.g. from Excel) | desktop only |
Common mistakes
- ❌
pd.read_csv("C:\Users\new_data\ipl.csv")written with single backslashes —\nbecomes a newline and the path breaks. ✅ User"...", double backslashes, or forward slashes. - ❌ Getting one giant column like
player;team;runs. ✅ The separator is wrong — passsep=";"(or"\t","|"). - ❌ The first data row has become your column names. ✅ The file has no header — use
header=Noneandnames=[...]. - ❌
pd.read_csv(csv_text)with the text itself. ✅ pandas treats a plain string as a file path; wrap text inio.StringIO(csv_text).
Interview tip
Q: Your CSV loads as a DataFrame with only one column. What happened?
A: The file uses a different delimiter (often ; or a tab). pandas split on commas, found none, and kept each whole line as a single value. Fix it with sep=";" or sep="\t". Checking df.shape right after loading catches this immediately.
Key points to remember
- pd.read_csv() reads delimited text (a file path, a URL or a file-like object) and returns a DataFrame.
- Line 1 becomes the column names by default (header=0); pandas infers int64 / float64 / str for each column.
- Use sep to change the separator — ';', '\t' or '|' — a single giant column means the separator is wrong.
- header=None means the file has no header row; names=[...] supplies your own column names.
- header=n or skiprows=n skips title/junk lines at the top of the file.
- Write Windows paths as r"C:\...", with double backslashes, or with forward slashes.
- io.StringIO(text) turns a string into a file-like object — perfect for practising without real files.
- Pandas 3 shows text columns as dtype str (pandas 2 showed object).
Try it yourself
Read a CSV (simulated with io.StringIO)
sep, header=None and names
Skip a title line and read tab-separated data
Practice: load the Purple Cap table
Revision Flashcards
Tap a card to flip it and see the answer.
