pandas Cheatsheet
Useful Methods
Use this pandas reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Inspection and Summary
df.head(5) # first N rows df.tail(5) # last N rows df.sample(10) # random N rows df.sample(frac=0.1, random_state=42) df.info() # dtypes, non-null counts, memory df.describe() # stat summary (numeric by default) df.describe(include="all") df.shape # (rows, cols) df.dtypes # dtype per column df.memory_usage(deep=True) df.memory_usage(deep=True).sum() # total bytes
Type Utilities
pd.api.types.is_numeric_dtype(df["col"]) pd.api.types.is_string_dtype(df["col"]) pd.api.types.is_datetime64_any_dtype(df["col"]) isinstance(df["col"].dtype, pd.CategoricalDtype) # is_categorical_dtype deprecated ≥2.1 df.select_dtypes(include="number") df.select_dtypes(exclude=["object", "category"])
Deduplication
df.duplicated() # bool Series: True = duplicate row df.duplicated(subset=["a", "b"]) # duplicate on specific columns df.duplicated(keep="last") # mark earlier copies as duplicate df.duplicated(keep=False) # mark ALL copies df.drop_duplicates() # keep first occurrence df.drop_duplicates(subset=["a", "b"]) df.drop_duplicates(keep="last") df.drop_duplicates(keep=False) # drop all duplicated rows entirely
Sorting
df.sort_values("col") df.sort_values(["col1", "col2"], ascending=[True, False]) df.sort_values("col", na_position="first") df.sort_values("text", key=lambda s: s.str.lower()) # case-insensitive sort df.sort_index() df.sort_index(level="month") # sort by a MultiIndex level s.sort_values() s.rank() # rank (average by default) s.rank(method="min") # "average"|"min"|"max"|"first"|"dense" s.rank(pct=True) # fractional rank s.rank(ascending=False) # rank descending
pipe() — Chainable Custom Functions
def add_tax(df, rate=0.08): df["tax"] = df["price"] * rate return df result = ( df .pipe(add_tax, rate=0.1) .pipe(lambda d: d[d["tax"] > 1]) .reset_index(drop=True) )
assign() — Chainable Column Creation
df = (
df
.assign(total=df["price"] * df["qty"])
.assign(discount=lambda d: d["total"] * 0.05)
.assign(final=lambda d: d["total"] - d["discount"])
)eval() and query() — Expression Strings
df.eval("a + b * c") # returns Series df.eval("total = price * qty", inplace=True) # adds column df.query("score > 50 and status == 'active'") df.query("city in ['NYC', 'LA']") threshold = 30 df.query("age > @threshold") # @ references local variable
String Methods (str Accessor)
s.str.lower() / s.str.upper() / s.str.title() s.str.strip() / s.str.lstrip() / s.str.rstrip() s.str.replace("old", "new") s.str.replace(r"\s+", "_", regex=True) s.str.contains("pattern", na=False, case=False) s.str.startswith("prefix") s.str.endswith("suffix") s.str.split(",") # → list per cell s.str.split(",", expand=True) # → DataFrame of splits s.str.get(0) # first element after split s.str.join("-") # join list elements s.str.len() # length of each string s.str.count("a") # occurrences of pattern s.str.extract(r"(\d+)") # first capture group → DataFrame s.str.extractall(r"(\d+)") # all matches → multi-row result s.str.findall(r"\d+") # list of all matches s.str.zfill(5) # zero-pad to width s.str.pad(10, side="left") s.str.center(20, fillchar="-") s.str.slice(0, 5) # s.str[0:5] s.str.cat(sep=", ") # concatenate all strings in Series s.str.get_dummies(sep="|") # one-hot from delimited strings
map(), apply(), applymap() / map() on DataFrame
# Series.map — element-wise, dict or callable s.map({"a": 1, "b": 2}) s.map(str.upper) # Series.apply — like map but callable only, richer output support s.apply(lambda x: x**2) # DataFrame.apply — column-wise or row-wise df.apply(np.sum) # per column df.apply(np.sum, axis=1) # per row # DataFrame element-wise (pandas ≥ 2.1: map; older: applymap) df.map(lambda x: x**2) # new name df.applymap(lambda x: x**2) # old name (deprecated 2.1)
Utility Functions
pd.isna(val) # True for NaN / None / NaT / pd.NA pd.notna(val) pd.to_numeric(s, errors="coerce") pd.to_datetime(s, errors="coerce") pd.to_timedelta(s, unit="s") pd.cut(s, bins=5) # equal-width bins pd.cut(s, bins=[0, 18, 65, 120], labels=["child", "adult", "senior"]) pd.qcut(s, q=4) # equal-frequency bins pd.qcut(s, q=4, labels=["Q1","Q2","Q3","Q4"]) pd.get_dummies(s) pd.factorize(s) # integer codes + unique array pd.interval_range(start=0, end=10, periods=5) pd.arrays.IntervalArray.from_breaks([0, 1, 3, 6])
Iteration (prefer vectorized, but when needed)
# Iterate rows — slow for idx, row in df.iterrows(): # each row as Series print(idx, row["col"]) for row in df.itertuples(index=True, name="Row"): # faster, namedtuple print(row.col) # Iterate columns for col_name, col_series in df.items(): print(col_name, col_series.dtype)
Avoid
iterrows()for numeric operations — it's orders of magnitude slower than vectorized methods.
reindex() and align()
# Conform to a new set of labels (NaN for missing) df.reindex([0, 1, 2, 99]) df.reindex(columns=["a", "b", "c", "new_col"]) df.reindex(new_index, fill_value=0) df.reindex(new_index, method="ffill") # fill gaps # align() — conform two objects to the same index simultaneously left, right = df1.align(df2, join="outer", fill_value=0)
clip(), round(), abs()
df["val"].clip(lower=0, upper=100) df.clip(lower=-3, upper=3) # all columns df["price"].round(2) df.round({"price": 2, "qty": 0}) df["amount"].abs() df.abs()
Displaying Options
pd.set_option("display.max_rows", 100) pd.set_option("display.max_columns", 50) pd.set_option("display.float_format", "{:.2f}".format) pd.set_option("display.width", 120) pd.reset_option("all") # restore defaults # Context manager for temporary settings with pd.option_context("display.max_rows", 200): print(df)
Styling (Jupyter)
df.style.highlight_max(color="lightgreen") df.style.highlight_min(color="salmon") df.style.background_gradient(cmap="Blues") df.style.format({"price": "${:.2f}", "pct": "{:.1%}"}) df.style.bar(subset=["score"], color="#aaffaa") df.style.hide(axis="index")