Working with CSV Files in Python: Simplify Data Processing and Analysis
CSV (Comma-Separated Values) files remain the most common format for sharing and storing tabular data in data science. Python offers two primary ways to work with them — the built-in csv module for low-level control and pandas.read_csv() for high-level efficiency. Mastering both lets you load, clean, and analyze data quickly while respecting memory limits and data types.
TL;DR — Recommended Approaches
- Use
pd.read_csv()for most data science tasks - Use
csv.DictReaderfor memory-efficient streaming - Always specify
dtypesandchunksizefor large files - Combine with list/dict comprehensions for fast post-processing
1. Quick Start with pandas (Most Common)
# Create small demo files so this example runs as-is
import pandas as pd
# Small inline sample so this example runs as-is.
# In a real project you would load it with pd.read_csv("sales_data.csv")
df = pd.DataFrame({
"customer_id": [101, 102, 103, 104, 105, 106],
"customer_name": ["Ana", "Ben", "Chen", "Dana", "Eli", "Fay"],
"order_date": ["2026-01-05", "2026-01-12", "2026-02-03",
"2026-02-18", "2026-03-01", "2026-03-09"],
"amount": [1250.75, 890.50, 2340.00, 1780.25, 2615.40, 450.00],
"quantity": [3, 2, 5, 4, 6, 1],
"profit": [312.69, 222.63, 585.00, 445.06, 653.85, 112.50],
"region": ["North", "South", "East", "North", "West", "South"],
"category": ["Electronics", "Books", "Electronics", "Home", "Home", "Books"],
"rating": [5, 4, None, 3, 5, 4],
"year": [2025, 2025, 2026, 2026, 2026, 2026],
"description": ["fast laptop", "python book", "noise cancelling headphones",
"desk lamp", "standing desk", "data science book"],
})
df.to_csv("sales_data.csv", index=False)
df.to_csv("large_sales.csv", index=False)
# Basic read with type optimization
df = pd.read_csv("sales_data.csv",
dtype={"customer_id": "int32", "amount": "float32"},
parse_dates=["order_date"])
print(df.dtypes)
print(f"Memory usage: {df.memory_usage(deep=True).sum() / (1024**2):.2f} MB")
2. Memory-Efficient Streaming with csv Module
import csv
with open("large_sales.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader: # processes row by row
amount = float(row["amount"])
if amount > 1000:
print(f"High value: {row['customer_id']}")
3. Real-World Data Science Examples
# Example 1: Chunked processing for huge files
chunk_size = 100_000 # tune to your memory budget
for chunk in pd.read_csv("large_sales.csv", chunksize=chunk_size):
chunk["profit"] = chunk["amount"] * 0.25
print(f"Processed {len(chunk):,} rows")
# Example 2: Convert CSV rows to list of dicts (clean & fast)
with open("sales_data.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
records = [row for row in reader] # list of dicts
# Example 3: Selective column loading
df = pd.read_csv("sales_data.csv", usecols=["customer_id", "amount", "region"])
4. Best Practices in 2026
- Always specify
dtypesandparse_dateswhen using pandas - Use
chunksizefor any file larger than a few GB - Prefer
csv.DictReaderfor pure streaming or very low-memory scenarios - Use
usecolsto load only needed columns - Save processed results to Parquet for faster future reads
csv Module or pandas?
The standard-library csv module reads one row at a time as a list or dict of strings. It uses very little memory and has no dependencies, which makes it ideal for streaming filters, quick scripts and files larger than RAM. pandas reads the whole file (or a chunk) into a typed DataFrame, which is what you want for grouping, joining and statistics. Many pipelines use both: csv to pre-filter a huge raw file, pandas to analyse the result.
Always pass newline="" when opening a file for the csv module, and set the encoding explicitly. The Python docs recommend newline="" so quoted fields that contain line breaks are handled correctly.
Worked Example: Clean, Filter and Write Back
import csv
from pathlib import Path
Path("raw.csv").write_text(
"customer_id,amount,region\n"
"101,1250.75,North\n"
"102,,South\n"
"103,abc,East\n"
"104,2340.00,north\n",
encoding="utf-8",
)
kept, skipped = 0, []
with open("raw.csv", newline="", encoding="utf-8") as src, \
open("clean.csv", "w", newline="", encoding="utf-8") as dst:
reader = csv.DictReader(src)
writer = csv.DictWriter(dst, fieldnames=reader.fieldnames)
writer.writeheader()
for line_no, row in enumerate(reader, start=2): # line 1 is the header
try:
row["amount"] = f"{float(row['amount']):.2f}"
except ValueError:
skipped.append(line_no)
continue
row["region"] = row["region"].strip().title()
writer.writerow(row)
kept += 1
print(f"kept {kept} rows, skipped lines {skipped}")
print(Path("clean.csv").read_text(encoding="utf-8"))
Bad rows are reported by line number instead of crashing the whole job, and the region labels are normalised on the way through.
Common Mistakes
- Forgetting
newline="": on Windows this produces blank lines between rows when writing - Treating
csvvalues as numbers: they are always strings until you convert them - Splitting lines with
line.split(","): it breaks on quoted fields such as"Lahore, PK" - Loading a huge file in one go: use
chunksizeorusecolsin pandas
Quick Summary
- Use
csv.DictReader/DictWriterfor streaming, pandas for analysis - Open files with
newline=""and an explicit encoding - Convert and validate each field, and report the lines you skip
Conclusion
Working with CSV files is a foundational skill in data science. In 2026, combine pandas.read_csv() with smart dtype specification and chunking for most tasks, and fall back to the csv module when you need maximum memory efficiency. These techniques turn raw CSV files into clean, analysis-ready data structures (DataFrames, lists of dicts, or generators) while keeping your pipelines fast and scalable.
Next steps:
- Take one of your large CSV files and optimize the loading code using
dtypes,chunksize, orcsv.DictReader