Pandas Indexing: loc, iloc, Boolean Indexing, and Selection
You have a DataFrame with thousands of rows. You need row 42. You need every customer from Texas. You need the salary in the third row, second column. Pandas gives you three different ways to grab exactly the data you want — and confusing them is one of the most common beginner mistakes.
In this tutorial, you'll learn the difference between label-based indexing (loc), position-based indexing (iloc), and boolean indexing (filtering with conditions). By the end, you'll always know which tool to reach for.
What Is loc? (Label-Based Indexing)
loc selects data by label — the names of your rows and columns. Think of it like looking up a word in a dictionary by its key, not by its page number.
What Is iloc? (Position-Based Indexing)
iloc selects data by integer position — like indexing a list. It doesn't care about labels. Row 0 is the first row, row 1 is the second, and so on.
df.loc[0:2] # rows with LABELS 0, 1, 2
# Returns 3 rowsdf.iloc[0:2] # rows at POSITIONS 0, 1
# Returns 2 rowsWhat Are .at and .iat? (Single-Value Access)
If you only need a single value, use .at (by label) or .iat (by position). They're faster than loc/iloc for scalar access because they skip the overhead of returning a Series or DataFrame.
How Does Boolean Indexing Work?
Boolean indexing is how you filter rows based on a condition. You write a condition that produces True/False for each row, then pass it into the brackets. Only the True rows survive.
You can combine multiple conditions using & (and), | (or), and ~ (not). Each condition must be wrapped in parentheses.
Can You Filter with .query()?
The .query() method lets you write filter conditions as a string. It's more readable for complex filters and avoids the bracket-and-ampersand clutter.
You can also reference external variables in .query() by prefixing them with @:
How Do You Update Values in a DataFrame?
You can use loc or at to set values too. This is how you update specific cells or entire columns based on conditions.
How Do You Filter for Multiple Values?
When you want to check if a column value is one of several options, use .isin(). It's cleaner than chaining multiple == conditions with |.
mask = (df['city'] == 'NYC') | (df['city'] == 'LA') | (df['city'] == 'Chicago')
result = df[mask]result = df[df['city'].isin(['NYC', 'LA', 'Chicago'])]Quick Reference: When to Use What
Choosing the right indexer is straightforward once you ask yourself two questions:
loc for labels, iloc for positions..at/.iat for a single cell (faster), loc/iloc for slices..query()..isin().Practice Exercises
Given the DataFrame below with a custom index, use loc to select the row with label 'b' and print the 'name' value from that row.
Use iloc to select the last two rows of the DataFrame and print their names as a list using .tolist().
Filter the DataFrame to find all employees with a salary greater than 70000. Print the names of matching employees as a list.
Filter the DataFrame to find people who are older than 25 AND live in NYC. Print their names as a list.
This code tries to filter rows where age is greater than 25 OR city is LA, but it raises an error. Fix the code so it prints the correct names as a list.
Use loc to set the 'status' column to 'pass' for all rows where score >= 70, and 'fail' for rows where score < 70. Print the status column as a list.