← All cheatsheets

Pandas Cheatsheet

Series/DataFrame selection, groupby, merge/concat, reshaping, time series, and MultiIndex.

Import & Creation

import pandas as pd

pd.Series([1, 2, 3])                        # 1-D labeled array
pd.Series({"a": 1, "b": 2})                 # from a dict -> keys become the index
pd.DataFrame({"a": [1, 2], "b": [3, 4]})    # from a dict of columns
pd.DataFrame([{"a": 1, "b": 2}, {"a": 3, "b": 4}])  # from a list of records
pd.read_csv("f.csv"); df.to_csv("f.csv", index=False)

Inspecting Data

df.head(); df.tail()
df.shape; df.columns; df.index; df.dtypes
df.info(); df.describe()          # describe() -> count/mean/std/min/quartiles/max
df.isnull().sum()                 # missing-value count per column

Selection & Indexing

df["col"]; df[["col1", "col2"]]        # select column(s) -> Series / DataFrame
df.loc[row_label, col_label]           # label-based
df.iloc[row_pos, col_pos]              # position-based (integer)
df.loc[df["age"] > 30]                 # boolean mask
df[df["animal"].isin(["cat", "dog"])]  # membership filter
df.query("age > 30 and visits == 1")   # string-expression filter
df.at[row, col]; df.iat[row_pos, col_pos]   # fast scalar access

Adding / Transforming Columns

df["new"] = df["a"] + df["b"]              # vectorized — prefer this over apply
df["new"] = df["a"].apply(lambda x: x * 2) # element-wise function (slower)
df.assign(new=lambda d: d["a"] * 2)        # returns a new DataFrame (chainable)
df["a"].map({"cat": 1, "dog": 2})          # map values via a dict/function
df.replace({"yes": True, "no": False})     # replace matching VALUES anywhere in the df/column
df["a"].replace({"yes": True, "no": False})     # ...or scoped to a single column
df.replace({"yes": True, "no": False}, inplace=True)   # mutate in place instead of returning a copy
df.astype({"age": int})                    # cast specific columns
df.rename(columns={"old": "new"}, index={0: "first"})
df.drop(columns=["a"]); df.drop(index=[0, 1])

Missing Data

df.isnull(); df.notnull()
df.dropna()                       # drop rows with ANY missing value
df.dropna(thresh=2)               # keep rows with at least 2 non-missing values
df.fillna(0)                      # fill with a constant
df["a"].fillna(df["a"].mean())    # fill with a computed value
df.interpolate()                  # linear interpolation of gaps
s1.add(s2, fill_value=0)          # arithmetic that treats a missing side as 0
s.nunique(dropna=False)           # count NaN as its own distinct value

String / Text / Regex (the .str accessor)

df["s"].str.lower(); .str.upper(); .str.strip()
df["s"].str.len()                          # length of each string
df["s"].str.contains(r"^Will\\b", regex=True)   # regex filter
df["s"].str.replace("a", "b", regex=False)
df["s"].str.split("_", expand=True)        # split into separate columns
df["s"].str.extract(r"(\\d+)")              # regex capture group -> new column
df["a"].str.cat(df["b"], sep="_")          # concatenate two string columns
df["s"].str.slice(start=-2)                # last two characters
df["tags"].str.get_dummies(sep=":")        # one-hot encode a multi-value column

GroupBy & Aggregation

df.groupby("animal")["age"].mean()
df.groupby("animal").agg({"age": "mean", "visits": "sum"})
df.groupby("animal").agg(avg_age=("age", "mean"), total_visits=("visits", "sum"))  # named agg
df.groupby("animal").get_group("dog")            # extract one group
df.groupby("animal").filter(lambda g: g["visits"].sum() > 5)   # keep whole groups
df.groupby("animal")["age"].transform(lambda x: (x - x.mean()) / x.std())  # per-group, same shape as input
df.pivot_table(values="age", index="animal", columns="priority", aggfunc="mean")
pd.crosstab(df["animal"], df["priority"])

.agg/.apply return one row per group (shape shrinks); .transform returns one row per original row (same shape as the input, values broadcast per group).

Merging, Joining, Concatenating

pd.concat([df1, df2])                          # stack rows (union of columns)
pd.concat([df1, df2], ignore_index=True)       # + reset to a fresh 0-based index
pd.concat([df1, df2], keys=["a", "b"])         # + hierarchical outer index label
pd.concat([df1, df2], axis=1, join="outer")    # side by side, aligned on index
pd.merge(df1, df2, on="key", how="inner")      # SQL-style join; how = inner/left/right/outer
pd.merge(df1, df2, left_on="a_id", right_on="id", how="left")  # differently-named keys
df1.join(df2, how="left")                      # index-to-index join shorthand

Reshaping

df.pivot(index="date", columns="ticker", values="price")   # long -> wide
df.melt(id_vars=["id"], value_vars=["a", "b"])              # wide -> long
df.set_index(["a", "b"]).unstack()                          # move an index level to columns
df.stack()                                                   # move columns into the index
pd.get_dummies(df["category"])                               # one-hot encode a column

Time Series

pd.to_datetime(df["date"])
pd.date_range("2020-01-01", periods=10, freq="D")   # D=day, "3D"=every 3 days, B=business day
s.resample("h").mean()               # aggregate into fixed time buckets
s.asfreq("3D", method="ffill")       # re-index onto a new frequency, forward-fill gaps
s.shift(1)                            # lag/lead by n periods
s.rolling(window=3).mean()            # rolling/moving statistics
s.index.month; s.index.year; s.index.is_leap_year   # via the .dt / DatetimeIndex accessor
np.busday_offset(dates, offsets=-10, roll="backward")   # shift by business days

MultiIndex

df.set_index(["date", "ticker"])
df.xs("AAPL", level="ticker")               # cross-section: fix one level
df.loc[("2020-01-01", "GOOGL"), "open":"close"]  # tuple key + column slice
df.swaplevel(); df.sort_index()

Sorting, Ranking, Duplicates

df.sort_values("age", ascending=False)
df.sort_values(["a", "b"])                  # multi-column sort
df["a"].rank()
df.nlargest(3, "age"); df.nsmallest(3, "age")
df.duplicated(subset=["a", "b"], keep="last")   # flag dupes, keeping the last occurrence
df.drop_duplicates()
df["a"].value_counts()                      # frequency of each value
df["a"].unique()

Gotchas

Also see: NumPy, PyTorch