Python pandas Cheat Sheet
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.
| Task | Code | Result |
|---|---|---|
| Series from a list | pd.Series([3, 5, 8]).tolist() | [3, 5, 8] |
| Series with a custom index | pd.Series([3, 5], index=["a", "b"]).to_dict() | {'a': 3, 'b': 5} |
| Rows in a DataFrame | len(df) | 4 |
| Shape (rows, columns) | df.shape | (4, 3) |
| Column names | df.columns.tolist() | ['student', 'city', 'score'] |
| Check a column's type | df["score"].dtype == "int64" | True |
| First 2 rows | df.head(2)["student"].tolist() | ['Asha', 'Ben'] |
| Last row | df.tail(1)["student"].tolist() | ['Dia'] |
| DataFrame from a list of dicts | pd.DataFrame([{"a": 1, "b": 2}, {"a": 3, "b": 4}]).values.tolist() | [[1, 2], [3, 4]] |
| Read a CSV file | pd.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.
| Task | Code | Result |
|---|---|---|
| One column (a Series) | df["score"].tolist() | [82, 91, 67, 74] |
| Several columns | df[["student", "score"]].shape | (4, 2) |
| Row by label | df.loc[1, "student"] | 'Ben' |
| Row by position | df.iloc[0]["student"] | 'Asha' |
| Cell by position | df.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 rows | df[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 list | df[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.
| Task | Code | Result |
|---|---|---|
| Sum | s.sum() | 314 |
| Mean | s.mean() | 78.5 |
| Median | s.median() | 78.0 |
| Largest value | s.max() | 91 |
| Label of the largest | s.idxmax() | 1 |
| Count of rows | s.count() | 4 |
| Count per value | df["city"].value_counts().sort_index().to_dict() | {'Oslo': 2, 'Pune': 2} |
| Unique values | sorted(df["city"].unique().tolist()) | ['Oslo', 'Pune'] |
| Number of unique values | df["city"].nunique() | 2 |
| Two highest scores | s.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.
| Task | Code | Result |
|---|---|---|
| Add a column from a calculation | df.assign(bonus=df["score"] + 5)["bonus"].tolist() | [87, 96, 72, 79] |
| Add a constant column | df.assign(year=2025)["year"].tolist() | [2025, 2025, 2025, 2025] |
Conditional column with np.where | np.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 function | s.apply(lambda x: x // 10).tolist() | [8, 9, 6, 7] |
| Rename columns | df.rename(columns={"score": "marks"}).columns.tolist() | ['student', 'city', 'marks'] |
| Drop a column | df.drop(columns=["city"]).columns.tolist() | ['student', 'score'] |
| Drop rows by label | df.drop(index=[0, 1])["student"].tolist() | ['Chen', 'Dia'] |
| Change a data type | s.astype(float).tolist() | [82.0, 91.0, 67.0, 74.0] |
| Upper-case text | df["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]}).
| Task | Code | Result |
|---|---|---|
| Sort by a column | df.sort_values("score")["student"].tolist() | ['Chen', 'Dia', 'Asha', 'Ben'] |
| Sort descending | df.sort_values("score", ascending=False)["student"].tolist() | ['Ben', 'Asha', 'Dia', 'Chen'] |
| Sort by two columns | df.sort_values(["city", "score"])["student"].tolist() | ['Dia', 'Ben', 'Chen', 'Asha'] |
| Reset the index after sorting | df.sort_values("score").reset_index(drop=True).index.tolist() | [0, 1, 2, 3] |
| Set a column as index | df.set_index("student").loc["Ben", "score"] | 91 |
| Top 2 rows by score | df.nlargest(2, "score")["student"].tolist() | ['Ben', 'Asha'] |
| Remove duplicate rows | len(dirty.drop_duplicates()) | 3 |
| Detect duplicate rows | dirty.duplicated().tolist() | [False, True, False, False] |
| Sum of the first 3 rows | df.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.
| Task | Code | Result |
|---|---|---|
| Count missing values per column | dirty.isna().sum().to_dict() | {'item': 0, 'price': 1} |
| Flag missing values | dirty["price"].isna().tolist() | [False, False, True, False] |
| Drop rows with any missing value | len(dirty.dropna()) | 3 |
| Fill missing with a value | dirty["price"].fillna(0).tolist() | [2.5, 2.5, 0.0, 4.0] |
| Fill missing with the mean | dirty["price"].fillna(dirty["price"].mean()).round(2).tolist() | [2.5, 2.5, 3.0, 4.0] |
| Replace a value | dirty["item"].replace("cap", "hat").tolist() | ['pen', 'pen', 'book', 'hat'] |
| Strip spaces from text | pd.Series([" a ", "b "]).str.strip().tolist() | ['a', 'b'] |
| Text to numbers | pd.to_numeric(pd.Series(["1", "2"])).tolist() | [1, 2] |
| Round numbers | pd.Series([1.234, 5.678]).round(1).tolist() | [1.2, 5.7] |
| Check text contains | df["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.
| Task | Code | Result |
|---|---|---|
| Mean score per city | df.groupby("city")["score"].mean().to_dict() | {'Oslo': 82.5, 'Pune': 74.5} |
| Sum per group | df.groupby("city")["score"].sum().to_dict() | {'Oslo': 165, 'Pune': 149} |
| Rows per group | df.groupby("city").size().to_dict() | {'Oslo': 2, 'Pune': 2} |
| Highest per group | df.groupby("city")["score"].max().to_dict() | {'Oslo': 91, 'Pune': 82} |
| Several statistics at once | df.groupby("city")["score"].agg(["min", "max"]).values.tolist() | [[74, 91], [67, 82]] |
| Named aggregation | df.groupby("city").agg(top=("score", "max"))["top"].to_dict() | {'Oslo': 91, 'Pune': 82} |
| Group mean added to each row | df.groupby("city")["score"].transform("mean").tolist() | [74.5, 82.5, 74.5, 82.5] |
| Pivot table | df.pivot_table(index="city", values="score", aggfunc="mean")["score"].to_dict() | {'Oslo': 82.5, 'Pune': 74.5} |
| Cross-tabulation counts | pd.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.
| Task | Code | Result |
|---|---|---|
| Inner join on a column | left.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 names | left.rename(columns={"student": "name"}).merge(right, left_on="name", right_on="student").shape | (2, 4) |
| Stack DataFrames vertically | len(pd.concat([left, left], ignore_index=True)) | 6 |
| Stack side by side | pd.concat([left, right], axis=1).shape | (3, 4) |
| Row count after an inner join | len(left.merge(right, on="student")) | 2 |
| Row count after an outer join | len(left.merge(right, on="student", how="outer")) | 4 |
| Column names after overlapping merge | list(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.
| Need | Use | Example |
|---|---|---|
| Rows by index label | loc | df.loc[1] |
| Rows by position | iloc | df.iloc[1] |
| Rows matching a rule | Boolean filter | df[df["score"] > 70] |
| Label slice, end included | loc | df.loc[0:1] gives 2 rows |
| Position slice, end excluded | iloc | df.iloc[0:1] gives 1 row |
| Rows and columns together | loc[rows, cols] | df.loc[df["score"] > 70, "student"] |
| Readable filter strings | query | df.query("score < 80") |
| Safe assignment into a filtered subset | loc | df.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.
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.
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.
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)])✓ 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())✓ 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 →