Skip to content

Pandas Cheat Sheet

Quick reference for data analysis with Pandas. One-liner + example for every operation.

import pandas as pd
import numpy as np

Loading Data

df = pd.read_csv("file.csv")
df = pd.read_csv("file.csv", parse_dates=["date_col"], dtype={"id": str})
df = pd.read_excel("file.xlsx", sheet_name="Sheet1")
df = pd.DataFrame({"a": [1, 2], "b": [3, 4]})   # from dict

Inspecting

df.shape           # (rows, cols)
df.info()          # dtypes, non-null counts
df.describe()      # summary stats for numeric cols
df.head(5)         # first 5 rows
df.tail(3)         # last 3 rows
df.columns.tolist()
df.dtypes
df.isnull().sum()           # missing per column
df.isnull().mean() * 100    # % missing per column
df["col"].value_counts()    # frequency table
df["col"].nunique()         # unique count

Selecting

df["col"]                         # single column → Series
df[["col1", "col2"]]              # multiple columns → DataFrame
df.loc[0:5, ["col1", "col2"]]     # rows 0-5, named columns
df.iloc[0:5, 0:3]                 # rows 0-4, columns 0-2 (position)
df.iloc[-1]                       # last row

Filtering

df[df["status"] == "completed"]
df[df["total"] > 100]
df[(df["status"] == "completed") & (df["total"] > 100)]   # AND
df[(df["status"] == "pending") | (df["status"] == "cancelled")]   # OR
df[~(df["status"] == "cancelled")]                          # NOT
df[df["status"].isin(["completed", "pending"])]             # IN
df[df["total"].between(50, 200)]                            # BETWEEN
df[df["delivery_date"].isna()]                              # IS NULL
df[df["email"].str.contains("@gmail", case=False)]          # LIKE
df.query("status == 'completed' and total > 100")           # query syntax

Adding & Modifying Columns

df["total"] = df["quantity"] * df["unit_price"]
df["order_size"] = np.where(df["total"] > 200, "Large", "Small")
df["label"] = df["status"].map({"completed": "Done", "pending": "Wait"})
df["log_total"] = np.log1p(df["total"])
df["order_month"] = df["order_date"].dt.month_name()

# Using assign (chain-friendly)
df = df.assign(
    total=lambda x: x["quantity"] * x["unit_price"],
    net=lambda x: x["total"] * 0.82,
)

# pd.cut — binning
df["tier"] = pd.cut(df["total"], bins=[0, 50, 200, float("inf")],
                    labels=["Budget", "Standard", "Premium"])

Renaming and Dropping

df.rename(columns={"old_name": "new_name"})
df.drop(columns=["col1", "col2"])
df.drop_duplicates()
df.drop_duplicates(subset=["order_id"], keep="first")
df.reset_index(drop=True)

Sorting

df.sort_values("total", ascending=False)
df.sort_values(["status", "total"], ascending=[True, False])
df.nlargest(5, "total")      # top 5 by total
df.nsmallest(3, "price")     # bottom 3 by price

GroupBy

df.groupby("category")["total"].sum()
df.groupby("category")["total"].agg(["count", "sum", "mean", "std"])

# Named aggregation
df.groupby("customer_id").agg(
    orders=("order_id", "count"),
    revenue=("total", "sum"),
    avg_order=("total", "mean"),
).reset_index()

# transform — keep original row count
df["customer_total"] = df.groupby("customer_id")["total"].transform("sum")

Merge and Concat

pd.merge(orders, customers, on="customer_id")                    # INNER
pd.merge(orders, customers, on="customer_id", how="left")       # LEFT JOIN
pd.merge(orders, customers, on="customer_id", how="outer")      # FULL OUTER
pd.concat([df1, df2], ignore_index=True)                         # vertical stack

Pivot Tables

pd.pivot_table(df, values="total", index="category",
               columns="status", aggfunc="sum", fill_value=0)

String Operations

df["col"].str.lower()
df["col"].str.strip()
df["col"].str.replace(r"\s+", " ", regex=True)
df["col"].str.contains("keyword")
df["col"].str.split(",", expand=True)    # → multiple columns
df["col"].str.len()

DateTime Operations

df["date"] = pd.to_datetime(df["date_str"])
df["year"] = df["date"].dt.year
df["month"] = df["date"].dt.month
df["month_name"] = df["date"].dt.strftime("%b")
df["dow"] = df["date"].dt.day_name()
df["quarter"] = df["date"].dt.quarter
df.set_index("date")["value"].resample("ME").sum()     # monthly aggregation
df["rolling_7d"] = df["revenue"].rolling(7).mean()
df["mom_change"] = df["revenue"].pct_change()
df["prev_month"] = df["revenue"].shift(1)

Missing Values

df.dropna()                                  # drop rows with ANY NaN
df.dropna(subset=["email"])                  # drop rows where email is NaN
df["discount"].fillna(0)                     # fill with 0
df.fillna(df.mean(numeric_only=True))        # fill numeric with column mean
df["price"].fillna(df.groupby("cat")["price"].transform("median"))  # group median
df["value"].ffill()                          # forward fill
df["value"].interpolate()                    # linear interpolation

Useful Shortcuts

df["col"].unique()                    # array of unique values
df["col"].value_counts(normalize=True)  # relative frequency
df.memory_usage(deep=True).sum()      # memory in bytes
df["col"].astype("category")          # reduce memory for low-cardinality strings
df.apply(func, axis=1)                # row-wise function
df.pipe(func)                         # chain custom function
df.to_csv("output.csv", index=False)
df.to_excel("output.xlsx", index=False)