Pandas
Advanced 13 min read Pandas

Pandas Performance

Make big frames behave

Millions of rows only feel fast when you think vectorized. dtype choices, avoidable loops, and copy churn decide whether a job runs in seconds or stalls the notebook.

vectorizationdtypememorychunksapplyefficientprofiling
Before we start

What you will learn

  • Replace row-wise Python loops with vectorized ops
  • Choose dtypes to cut memory drastically
  • Profile and chunk heavy workflows
Introduction

What is this?

Performance in pandas comes from using C-optimized vectorized operations over whole columns instead of Python-level loops. dtype hygiene (category, int8/16, float32) shrinks memory. apply() with a Python lambda is often a loop in disguise; merging, groupby and joins are designed to be fast. When frames exceed RAM, chunked reads and processing win.

Motivation

Why do you need it?

  • A 10M-row 'if plan matches, add flag' loop runs minutes; a vectorized np.where runs milliseconds.
  • Correct dtypes cut memory 4-10x — the difference between OOM and a quiet job.
  • apply over a groupby can be catastrophically slow; agg/transform stay C-fast.
  • Dashboards and pipelines only stay live if the query cost is tiny.
Think about it

Mental model

Imagine

A warehouse crew scanning a whole pallet at once

Think of

Vectorized pandas

Scanning 1,000 boxes one at a time is telling each worker to walk each box; scanning rows means reading the pallet's barcode once. dtypes are choosing sturdy light pallets; profiling is counting which stations actually cost time before you upgrade anything.

Mechanics

How it works

  • Vectorized ops (>, +, str methods, np.where, .clip) run on whole arrays in C.
  • Avoid Python loops over rows; replace with numpy functions or vectorized pandas methods.
  • Memory mining: category for low-cardinality strings, int8/int16/float32 for bounded numerics.
  • apply is convenient but Python-speed; .map()/.vectorized lambdas or np routines beat it.
  • Chunking: read_csv(chunksize=...) processes in blocks; concatenate only the needed aggregates.
  • Measure first: df.info(memory_usage='deep') and ._repr_sql() / time-based profiling target the fix.

The speed pyramid.

Vectorized ops
C-level methods
np.where maps
apply/lambda
Row loops
Hands-on

Examples

Loop vs vectorized, same flag

Loop vs vectorized, same flag
import numpy as np, pandas as pd
df = pd.DataFrame({"plan": ["pro", "basic", "pro", "basic"] * 250000})
def loop(df):
out = []
for p in df.plan:
out.append("key" if p == "pro" else "std")
df2 = df.copy(); df2["seg"] = out; return df2
df["seg"] = np.where(df.plan == "pro", "key", "std")
print(df.groupby("seg").size())
# loop(df) # same answer, orders of magnitude slower

np.where assigns a whole column in one C pass; the equivalent Python loop iterates each row through the interpreter.

Real world

In production

  • A 20M-row event frame converts plan/user_type to category dtype and drops memory 6x before grouping.
  • A nightly feature job chunks 50GB CSVs and aggregates per chunk, never materializing the full frame.
  • A dashboard query replaces an apply() with np.select and drops latency from 40s to under a second.
Guidelines

Best practices

  • Vectorize first, optimize later — profile before micro-tuning.
  • Use pd.cut/np.select for multi-way flags instead of stacked conditions.
  • Mind the penalty of object dtype strings; convert stable columns to category.
  • Keep the column set lean: drop unneeded columns pre-groupby to cut memory.
Watch out

Common mistakes

  • Writing a Python loop to build a flag that np.where does in one line.
  • Leaving every string an object dtype and watching memory explode.
  • Using apply where .map with a dict or numpy works.
  • Optimizing a 10MB frame when a 10GB sibling is the real problem.
When things break

Debugging tips

  • df.info(memory_usage='deep') shows where the giant allocation hides.
  • Timing with %timeit on one op beats guessing which step is slow.
  • If a chunked run differs from full-frame results, check chunk boundaries for state leakage.
  • A category dtype misbehaving in math is storage, not content — convert back for arithmetic.
Interviews

Interview checkpoint

Test yourself

Quick quiz

0/2
1

Which is typically fastest for a conditional flag?

2

Storing low-cardinality strings as 'category' reduces memory.

Go deeper

Official documentation