Cheat sheetData tools

Python pandas Cheat Sheet

Short answer
pandas works on tables: select with df["col"], df.loc[...] and df[df["score"] > 70], clean with fillna and dropna, summarise with df.groupby("city")["score"].mean(), and combine tables with merge.

This page lists the pandas calls you reach for every day, each with a small input and the result you get. If an idea is unfamiliar, read pandas basics first, then the lessons on selecting data, cleaning, groupby and merging.

Install with pip install pandas, then import pandas as pd. The examples were checked on current pandas 2.x and 3.x releases; the calls avoid behaviour that changed between them.

Create pandas Series and DataFrames and inspect them

Tables use import pandas as pd, import numpy as np and this DataFrame:

df = pd.DataFrame({
    "student": ["Asha", "Ben", "Chen", "Dia"],
    "city": ["Pune", "Oslo", "Pune", "Oslo"],
    "score": [82, 91, 67, 74],
})
s = df["score"]

Most results are shown with .tolist() or .to_dict() so you see plain Python values. Start with pandas basics.

Creating and inspecting data
TaskCodeResult
Series from a listpd.Series([3, 5, 8]).tolist()[3, 5, 8]
Series with a custom indexpd.Series([3, 5], index=["a", "b"]).to_dict(){'a': 3, 'b': 5}
Rows in a DataFramelen(df)4
Shape (rows, columns)df.shape(4, 3)
Column namesdf.columns.tolist()['student', 'city', 'score']
Check a column's typedf["score"].dtype == "int64"True
First 2 rowsdf.head(2)["student"].tolist()['Asha', 'Ben']
Last rowdf.tail(1)["student"].tolist()['Dia']
DataFrame from a list of dictspd.DataFrame([{"a": 1, "b": 2}, {"a": 3, "b": 4}]).values.tolist()[[1, 2], [3, 4]]
Read a CSV filepd.read_csv("scores.csv")a DataFrame of the file's rows

Select pandas columns and rows with loc, iloc and filters

Use loc for labels and iloc for positions. Boolean filters need &, | and parentheses. Details in selecting data in pandas.

Selecting and filtering
TaskCodeResult
One column (a Series)df["score"].tolist()[82, 91, 67, 74]
Several columnsdf[["student", "score"]].shape(4, 2)
Row by labeldf.loc[1, "student"]'Ben'
Row by positiondf.iloc[0]["student"]'Asha'
Cell by positiondf.iloc[2, 2]67
Slice rows by label (end included)df.loc[0:1, "score"].tolist()[82, 91]
Slice rows by position (end excluded)df.iloc[0:2]["score"].tolist()[82, 91]
Filter rowsdf[df["score"] > 70]["student"].tolist()['Asha', 'Ben', 'Dia']
Combine conditions with &df[(df["score"] > 70) & (df["city"] == "Oslo")]["student"].tolist()['Ben', 'Dia']
Value in a listdf[df["city"].isin(["Pune"])]["student"].tolist()['Asha', 'Chen']
Filter with query()df.query("score < 80")["student"].tolist()['Chen', 'Dia']

pandas summary statistics: sum, mean, median and value_counts

Column methods skip missing values by default. See pandas basics.

Summary statistics
TaskCodeResult
Sums.sum()314
Means.mean()78.5
Medians.median()78.0
Largest values.max()91
Label of the largests.idxmax()1
Count of rowss.count()4
Count per valuedf["city"].value_counts().sort_index().to_dict(){'Oslo': 2, 'Pune': 2}
Unique valuessorted(df["city"].unique().tolist())['Oslo', 'Pune']
Number of unique valuesdf["city"].nunique()2
Two highest scoress.nlargest(2).tolist()[91, 82]
Rank (1 = lowest)s.rank().tolist()[3.0, 4.0, 1.0, 2.0]

Add, rename, drop and convert pandas columns

Most methods return a new DataFrame, so assign the result back or chain the next call. Prefer assign when you want a chain with no side effects.

Creating and changing columns
TaskCodeResult
Add a column from a calculationdf.assign(bonus=df["score"] + 5)["bonus"].tolist()[87, 96, 72, 79]
Add a constant columndf.assign(year=2025)["year"].tolist()[2025, 2025, 2025, 2025]
Conditional column with np.wherenp.where(df["score"] >= 75, "pass", "retry").tolist()['pass', 'pass', 'retry', 'retry']
Transform with map()df["city"].map({"Pune": "PN", "Oslo": "OS"}).tolist()['PN', 'OS', 'PN', 'OS']
Apply a functions.apply(lambda x: x // 10).tolist()[8, 9, 6, 7]
Rename columnsdf.rename(columns={"score": "marks"}).columns.tolist()['student', 'city', 'marks']
Drop a columndf.drop(columns=["city"]).columns.tolist()['student', 'score']
Drop rows by labeldf.drop(index=[0, 1])["student"].tolist()['Chen', 'Dia']
Change a data types.astype(float).tolist()[82.0, 91.0, 67.0, 74.0]
Upper-case textdf["city"].str.upper().tolist()['PUNE', 'OSLO', 'PUNE', 'OSLO']

Sort, index and de-duplicate a pandas DataFrame

Sorting keeps the old index labels; call reset_index(drop=True) for a fresh 0..n-1 index. dirty below is pd.DataFrame({"item": ["pen", "pen", "book", "cap"], "price": [2.5, 2.5, None, 4.0]}).

Sorting and duplicates
TaskCodeResult
Sort by a columndf.sort_values("score")["student"].tolist()['Chen', 'Dia', 'Asha', 'Ben']
Sort descendingdf.sort_values("score", ascending=False)["student"].tolist()['Ben', 'Asha', 'Dia', 'Chen']
Sort by two columnsdf.sort_values(["city", "score"])["student"].tolist()['Dia', 'Ben', 'Chen', 'Asha']
Reset the index after sortingdf.sort_values("score").reset_index(drop=True).index.tolist()[0, 1, 2, 3]
Set a column as indexdf.set_index("student").loc["Ben", "score"]91
Top 2 rows by scoredf.nlargest(2, "score")["student"].tolist()['Ben', 'Asha']
Remove duplicate rowslen(dirty.drop_duplicates())3
Detect duplicate rowsdirty.duplicated().tolist()[False, True, False, False]
Sum of the first 3 rowsdf.head(3)["score"].sum()240

Clean missing data and text in pandas

Check for missing values before you calculate. dirty is the same small price table as above. Read the pandas cleaning lesson for when to drop and when to fill.

Missing values and text cleaning
TaskCodeResult
Count missing values per columndirty.isna().sum().to_dict(){'item': 0, 'price': 1}
Flag missing valuesdirty["price"].isna().tolist()[False, False, True, False]
Drop rows with any missing valuelen(dirty.dropna())3
Fill missing with a valuedirty["price"].fillna(0).tolist()[2.5, 2.5, 0.0, 4.0]
Fill missing with the meandirty["price"].fillna(dirty["price"].mean()).round(2).tolist()[2.5, 2.5, 3.0, 4.0]
Replace a valuedirty["item"].replace("cap", "hat").tolist()['pen', 'pen', 'book', 'hat']
Strip spaces from textpd.Series([" a ", "b "]).str.strip().tolist()['a', 'b']
Text to numberspd.to_numeric(pd.Series(["1", "2"])).tolist()[1, 2]
Round numberspd.Series([1.234, 5.678]).round(1).tolist()[1.2, 5.7]
Check text containsdf["student"].str.contains("a").tolist()[True, False, False, True]

pandas groupby, pivot_table and crosstab

groupby splits rows into groups, applies a calculation and combines the results. Learn the idea in pandas groupby. Group keys come back sorted, which makes these results stable.

Grouping and aggregating
TaskCodeResult
Mean score per citydf.groupby("city")["score"].mean().to_dict(){'Oslo': 82.5, 'Pune': 74.5}
Sum per groupdf.groupby("city")["score"].sum().to_dict(){'Oslo': 165, 'Pune': 149}
Rows per groupdf.groupby("city").size().to_dict(){'Oslo': 2, 'Pune': 2}
Highest per groupdf.groupby("city")["score"].max().to_dict(){'Oslo': 91, 'Pune': 82}
Several statistics at oncedf.groupby("city")["score"].agg(["min", "max"]).values.tolist()[[74, 91], [67, 82]]
Named aggregationdf.groupby("city").agg(top=("score", "max"))["top"].to_dict(){'Oslo': 91, 'Pune': 82}
Group mean added to each rowdf.groupby("city")["score"].transform("mean").tolist()[74.5, 82.5, 74.5, 82.5]
Pivot tabledf.pivot_table(index="city", values="score", aggfunc="mean")["score"].to_dict(){'Oslo': 82.5, 'Pune': 74.5}
Cross-tabulation countspd.crosstab(df["city"], df["score"] > 70).values.tolist()[[0, 2], [1, 1]]

Merge, join and concat pandas DataFrames

left has student and score for Asha, Ben and Chen; right has student and club for Asha, Chen and Eli. Walk through the join types in pandas merge. Sort an outer join if you need a fixed order.

Combining DataFrames
TaskCodeResult
Inner join on a columnleft.merge(right, on="student")["student"].tolist()['Asha', 'Chen']
Left join (keep all left rows)left.merge(right, on="student", how="left")["club"].isna().tolist()[False, True, False]
Outer join (keep everything)left.merge(right, on="student", how="outer").sort_values("student")["student"].tolist()['Asha', 'Ben', 'Chen', 'Eli']
Join columns that have different namesleft.rename(columns={"student": "name"}).merge(right, left_on="name", right_on="student").shape(2, 4)
Stack DataFrames verticallylen(pd.concat([left, left], ignore_index=True))6
Stack side by sidepd.concat([left, right], axis=1).shape(3, 4)
Row count after an inner joinlen(left.merge(right, on="student"))2
Row count after an outer joinlen(left.merge(right, on="student", how="outer"))4
Column names after overlapping mergelist(left.merge(left, on="student", suffixes=("_a", "_b")).columns)['student', 'score_a', 'score_b']

loc vs iloc vs boolean filter: which to use

Three ways to pick rows, and when each fits.

Choosing a selection method
NeedUseExample
Rows by index labellocdf.loc[1]
Rows by positionilocdf.iloc[1]
Rows matching a ruleBoolean filterdf[df["score"] > 70]
Label slice, end includedlocdf.loc[0:1] gives 2 rows
Position slice, end excludedilocdf.iloc[0:1] gives 1 row
Rows and columns togetherloc[rows, cols]df.loc[df["score"] > 70, "student"]
Readable filter stringsquerydf.query("score < 80")
Safe assignment into a filtered subsetlocdf.loc[df["score"] < 70, "score"] = 70

Examples you can run

Press Run, then edit the code and run it again.

Average score per city, best first

Group, take the mean, then sort the result. Sorting makes the output order explicit.

Average score per city, best first
import pandas as pd

df = pd.DataFrame({
    "student": ["Asha", "Ben", "Chen", "Dia"],
    "city": ["Pune", "Oslo", "Pune", "Oslo"],
    "score": [82, 91, 67, 74],
})
avg = df.groupby("city")["score"].mean().sort_values(ascending=False)
print(avg.to_dict())
print(avg.index.tolist())
Expected output{'Oslo': 82.5, 'Pune': 74.5}
['Oslo', 'Pune']

Fill missing prices, then total per item

Fill the gap with the column mean, then group and sum.

Fill missing prices, then total per item
import pandas as pd

cart = pd.DataFrame({"item": ["pen", "pen", "book", "cap"], "price": [2.5, 2.5, None, 4.0]})
cart["price"] = cart["price"].fillna(cart["price"].mean())
print(cart["price"].tolist())
print(cart.groupby("item")["price"].sum().to_dict())
Expected output[2.5, 2.5, 3.0, 4.0]
{'book': 3.0, 'cap': 4.0, 'pen': 5.0}

Left join to find students without a club

A left join keeps every row of the left table; missing partners become NaN, which isna() can find.

Left join to find students without a club
import pandas as pd

left = pd.DataFrame({"student": ["Asha", "Ben", "Chen"], "score": [82, 91, 67]})
right = pd.DataFrame({"student": ["Asha", "Chen", "Eli"], "club": ["chess", "art", "music"]})
merged = left.merge(right, on="student", how="left")
print(merged[merged["club"].isna()]["student"].tolist())
print(len(merged))
Expected output['Ben']
3

Common mistakes

Using `and` to combine filters

✗ Wrong

import pandas as pd
df = pd.DataFrame({"score": [60, 80, 95]})
print(df[(df["score"] > 70) and (df["score"] < 90)])
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

✓ Right

import pandas as pd
df = pd.DataFrame({"score": [60, 80, 95]})
print(df[(df["score"] > 70) & (df["score"] < 90)]["score"].tolist())

Combine Boolean Series with & or |, each condition in parentheses.

Expecting sort_values to change the DataFrame

✗ Wrong

import pandas as pd
df = pd.DataFrame({"n": [3, 1, 2]})
df.sort_values("n")
print(df["n"].tolist())
[3, 1, 2] (nothing changed)

✓ Right

import pandas as pd
df = pd.DataFrame({"n": [3, 1, 2]})
df = df.sort_values("n")
print(df["n"].tolist())

Most pandas methods return a new object. Assign the result back or chain on it.

Python pandas Cheat Sheet: questions people ask

What is the difference between loc and iloc in pandas?

loc selects by index label and includes the end of a slice, while iloc selects by integer position and excludes the end. See selecting data in pandas.

How do I filter rows in a pandas DataFrame?

Put a Boolean condition inside square brackets: df[df["score"] > 70]. Combine conditions with & and |, each in parentheses.

How do I merge two DataFrames in pandas?

Call left.merge(right, on="key"), and choose how="inner", "left" or "outer" depending on which unmatched rows you want to keep. The pandas merge lesson shows each case.

Keep learning

Step-by-step lessons:
Pandas Basicspandas Selecting Datapandas groupby and Pivot Tables

Related:
Python NumPy Cheat Sheetpandas Data Cleaningpandas Merge, Join and ConcatPython Dictionaries

More in data tools:
Python NumPy Cheat Sheet See all →