Data Analysis with pandas · pandas Fundamentals
Selecting and Filtering Rows and Columns
Select data by label with loc, by position with iloc, filter rows with boolean conditions and isin, and use query for readable filters.
What you'll build
Answers to everyday questions about the orders table: orders from Germany, orders worth more than 20 euros, specific customers, and particular columns, using the three selection tools pandas provides.
The idea
df["col"]/df[["a", "b"]]: columns.df.loc[rows, cols]: by label (index values and column names), including boolean masks.df.iloc[rows, cols]: by position (0, 1, 2...).- Boolean masks combine with
&(and),|(or),~(not), each condition in parentheses. isin([...])tests membership;between(a, b)ranges;query("...")reads like a sentence.
The code
from io import StringIO
import pandas as pd
csv = StringIO("""order_id,date,customer,country,product,quantity,unit_price
1001,2026-01-03,ana,DE,mug,2,8.50
1002,2026-01-03,ben,US,teapot,1,24.00
1003,2026-01-04,chen,DE,kettle,1,31.90
1004,2026-01-05,ana,DE,teapot,1,24.00
1005,2026-01-07,dara,FR,mug,4,8.50
1006,2026-01-07,ben,US,mug,1,8.50
""")
orders = pd.read_csv(csv, parse_dates=["date"])
orders["total"] = orders["quantity"] * orders["unit_price"]
german = orders.loc[orders["country"] == "DE", ["order_id", "customer", "total"]]
print(german)
big_or_fr = orders[(orders["total"] > 20) | (orders["country"] == "FR")]
print(big_or_fr["order_id"].tolist())
print(orders.loc[orders["customer"].isin(["ana", "ben"]), "product"].unique().tolist())
print(orders.iloc[:2, :3])
print(orders.query("country == 'US' and quantity >= 1")["order_id"].tolist())
Output
order_id customer total 0 1001 ana 17.0 2 1003 chen 31.9 3 1004 ana 24.0 [1002, 1003, 1004, 1005] ['mug', 'teapot'] order_id date customer 0 1001 2026-01-03 ana 1 1002 2026-01-03 ben [1002, 1006]
Common mistakes
- Using
and/orinstead of&/|, or forgetting parentheses around each condition (ValueError: truth value of a Series is ambiguous). - Chained indexing like
df[df.x > 1]["y"] = 0: in pandas 3 (copy-on-write) it never modifiesdf. Usedf.loc[df.x > 1, "y"] = 0. - Mixing up
loc(labels, inclusive end) andiloc(positions, exclusive end).
Key points
- loc selects by label, iloc by position.
- Combine boolean conditions with &, |, ~ and parentheses.
- Assign with a single loc call, never chained indexing.
Further reading: Indexing and selecting data · Copy-on-Write
Practice questions
What's the difference between loc and iloc?
Answer
loc selects by labels (index values and column names, end inclusive); iloc selects by integer positions (end exclusive).
Why does (df.a > 1 and df.b < 5) raise an error?
Answer
Python's and/or need a single True/False; for element-wise logic on Series use & and | with parentheses around each condition.
Why doesn't df[df.x > 1]['y'] = 0 change df in pandas 3?
Answer
With copy-on-write, the first indexing returns a new object; assigning to it never affects df. Use df.loc[df.x > 1, 'y'] = 0.
Open in the app to mark lessons complete, take notes and track your progress.