pandas Cheatsheet
Modifying Data
Use this pandas reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Adding and Replacing Columns
# Simple assignment df["new_col"] = 0 df["full_name"] = df["first"] + " " + df["last"] df["score_pct"] = df["score"] / df["score"].max() * 100 # .assign() — returns new DataFrame, chainable df = df.assign(new_col=0) df = df.assign( tax=df["price"] * 0.08, total=lambda d: d["price"] + d["tax"], # use lambda to reference just-added cols ) # Insert at specific position df.insert(2, "new_col", df["a"] + df["b"]) # position, name, values
Renaming
# By mapping df.rename(columns={"old": "new", "a": "b"}) df.rename(index={0: "row_a", 1: "row_b"}) # With a function df.rename(columns=str.upper) df.rename(columns=lambda c: c.strip().lower().replace(" ", "_")) # Rename all columns at once (must provide all) df.columns = ["id", "name", "score"] # Rename index df.index.name = "record_id"
Dropping Columns and Rows
# Columns df.drop(columns=["col1", "col2"]) df.drop("col1", axis=1) # Rows by label df.drop(index=[0, 2, 5]) df.drop("row_a") # Rows by label range (loc-style) df.drop(df.index[2:5]) # In-place df.drop(columns=["tmp"], inplace=True)
Modifying Values — .loc / .at
# Safest way to modify values — avoids SettingWithCopyWarning df.loc[df["status"] == "active", "score"] += 10 df.loc[0, "name"] = "Alice" df.at[3, "score"] = 99 df.iat[0, 1] = 42
.apply() — Row-wise or Column-wise
# Along columns (axis=0, default) — function receives a column Series df.apply(lambda col: col.max() - col.min()) # Along rows (axis=1) — function receives a row Series df.apply(lambda row: row["a"] + row["b"], axis=1) # Apply to a single column df["score"].apply(lambda x: x * 1.1) df["name"].apply(str.upper) # Return multiple values → expands to columns df[["sin", "cos"]] = df["angle"].apply( lambda x: pd.Series({"sin": np.sin(x), "cos": np.cos(x)}) )
Performance note:
.apply()withaxis=1is slow — prefer vectorized operations (df["a"] + df["b"]),np.where, ordf.eval()when possible.
np.where and pd.cut — Vectorized Conditionals
import numpy as np # np.where(condition, value_if_true, value_if_false) df["label"] = np.where(df["score"] >= 60, "pass", "fail") # Nested np.where df["grade"] = np.where(df["score"] >= 90, "A", np.where(df["score"] >= 80, "B", np.where(df["score"] >= 70, "C", "F"))) # pd.cut — bin continuous values into categories df["bracket"] = pd.cut(df["age"], bins=[0, 18, 35, 65, 100], labels=["child", "young", "adult", "senior"]) # pd.qcut — quantile-based bins df["quartile"] = pd.qcut(df["score"], q=4, labels=["Q1", "Q2", "Q3", "Q4"])
.map() — Element-wise Mapping (Series)
# Via dict df["city_code"] = df["city"].map({"NYC": 1, "LA": 2, "Chicago": 3}) # Via function df["upper"] = df["name"].map(str.upper) # map() does NOT call the function with missing keys (→ NaN) # Use fillna() to handle misses df["code"] = df["city"].map(mapping).fillna(-1)
.replace() — Value Substitution
# Scalar replace df["col"].replace("old", "new") df.replace(np.nan, 0) # Dict of replacements df["status"].replace({"active": 1, "inactive": 0}) df.replace({"status": {"active": 1}, "grade": {"A": 4.0}}) # List: replace each element with corresponding replacement df["col"].replace(["bad", "worse"], ["ok", "ok"]) # Regex replace df["text"].replace(r"\s+", " ", regex=True) # replace() vs map(): replace keeps unmapped values; map() turns them to NaN
Sorting
# Sort by values df.sort_values("col") df.sort_values("col", ascending=False) df.sort_values(["col1", "col2"], ascending=[True, False]) df.sort_values("col", na_position="first") # "first" | "last" (default) df.sort_values("col", key=lambda s: s.str.lower()) # custom key # Sort by index df.sort_index() df.sort_index(ascending=False) df.sort_index(level="month") # MultiIndex: sort by one level # Stable sort (default since pandas 1.x uses mergesort for stability) df.sort_values("col", kind="stable")
Casting / Type Conversion
df["age"] = df["age"].astype(int) df["price"] = df["price"].astype(float) df["flag"] = df["flag"].astype(bool) df["cat"] = df["cat"].astype("category") df["text"] = df["text"].astype("string") # nullable StringDtype df["date"] = pd.to_datetime(df["date"]) df["n"] = pd.to_numeric(df["n"], errors="coerce") # invalid → NaN df = df.astype({"a": int, "b": float}) # multiple at once # Downcast numeric types to save memory df["n"] = pd.to_numeric(df["n"], downcast="integer") # "integer" | "float" | "signed" | "unsigned"
Clipping Values
df["score"].clip(lower=0, upper=100) df.clip(lower=0) # clip all columns df["val"].clip(lower=df["min_val"], upper=df["max_val"]) # per-row bounds
String Column Modifications
df["name"] = df["name"].str.strip() df["name"] = df["name"].str.lower() df["name"] = df["name"].str.upper() df["name"] = df["name"].str.title() df["name"] = df["name"].str.replace(r"\s+", "_", regex=True) df["name"] = df["name"].str.slice(0, 10) # truncate df["name"] = df["name"].str.pad(20, side="right", fillchar=" ")
Reordering Columns
# Explicit order df = df[["id", "name", "score", "date"]] # Move one column to the front cols = ["target"] + [c for c in df.columns if c != "target"] df = df[cols] # Sort columns alphabetically df = df.reindex(sorted(df.columns), axis=1)