luvv to helpDiscover the Best Free Online Tools
Topic 5 of 30

Indexing and Selection Loc Iloc At Iat

Learn Indexing and Selection Loc Iloc At Iat for free with explanations, exercises, and a quick test (for Data Analyst).

Published: December 20, 2025 | Updated: December 20, 2025

Why this matters

As a Data Analyst, you constantly slice, filter, and edit data. Mastering pandas indexers (.loc, .iloc, .at, .iat) lets you do this precisely and fast. Real tasks include:

  • Filtering users by date range and selecting only needed columns for a report
  • Fixing a single incorrect value quickly without copying data
  • Building reproducible data cleaning steps with clear label- or position-based logic
Quick tip

Choose the indexer by what you know: labels (.loc/.at) or positions (.iloc/.iat). Don’t mix them inside the same bracket pair.

Concept explained simply

You have two questions when selecting data:

  • Do I select by label (row/column names) or by position (0-based integers)?
  • Do I need a range/collection or a single cell?

Mental model

  • .loc: label-based selection for rows and columns. Endpoints in label slices are inclusive.
  • .iloc: position-based selection for rows and columns. Endpoints in slices follow Python’s exclusive stop.
  • .at: fastest label-based access for a single scalar (one row label + one column label).
  • .iat: fastest position-based access for a single scalar (one row position + one column position).

Quick reference

  • Row by labels: df.loc['Q2':'Q4']
  • Row by positions: df.iloc[1:4]
  • Row and columns by labels: df.loc['Q2':'Q4', ['city', 'sales']]
  • Row and columns by positions: df.iloc[1:4, [0, 2]]
  • Boolean filter (recommended): df.loc[df['sales'] > 100, ['city', 'sales']]
  • Single value by labels: df.at['Q3', 'sales']
  • Single value by positions: df.iat[2, 1]
Inclusive vs exclusive
  • .loc slice: df.loc['A':'C'] includes 'C'
  • .iloc slice: df.iloc[0:3] includes rows at positions 0,1,2

Worked examples

Example 1: Label-based selection with .loc

import pandas as pd

df = pd.DataFrame({
    'city': ['NY', 'NY', 'NY', 'NY'],
    'sales': [100, 120, 90, 110],
    'returns': [5, 3, 4, 2]
}, index=['Q1', 'Q2', 'Q3', 'Q4'])

# Rows Q2..Q4 (inclusive), columns 'city' and 'sales'
result = df.loc['Q2':'Q4', ['city', 'sales']]
print(result)
What happens?

The row slice 'Q2':'Q4' includes Q2, Q3, Q4 (inclusive end), and only the two specified columns are returned.

Example 2: Position-based selection with .iloc

import pandas as pd

df2 = pd.DataFrame({
    'A': [10, 20, 30, 40],
    'B': [1, 2, 3, 4],
    'C': [7, 8, 9, 10]
}, index=[101, 102, 103, 104])

# First 3 rows, last 2 columns by position
slice_pos = df2.iloc[:3, -2:]
print(slice_pos)
What happens?

Positions are 0-based, and the stop index is exclusive. -2: selects the last two columns (B, C).

Example 3: Fast scalar updates with .at and .iat

import pandas as pd

df = pd.DataFrame({
    'city': ['NY', 'NY', 'NY', 'NY'],
    'sales': [100, 120, 90, 110]
}, index=['Q1', 'Q2', 'Q3', 'Q4'])

# Update a single value by label
df.at['Q3', 'sales'] = 0

# Update a single value by position
# (row 0, col 1) becomes 200
val = df.iat[0, 1]
df.iat[0, 1] = val * 2

print(df)
Why .at/.iat?

They are optimized for single-cell get/set and avoid overhead of .loc/.iloc when you only need one scalar.

Example 4: Boolean filtering done right

import pandas as pd

df = pd.DataFrame({
    'dept': ['A', 'A', 'B', 'B'],
    'score': [70, 85, 60, 90]
})

mask = df['score'] >= 80
# Filter rows and select only 'dept'
high = df.loc[mask, ['dept']]
print(high)

# Safer assignment using .loc (avoids SettingWithCopy warnings)
df.loc[mask, 'score'] = df.loc[mask, 'score'] + 1

Exercises

Try these small tasks locally. Then open the solution to compare. Use the checklist to self-verify.

Exercise 1 — Label-based selection and scalar update

Create the DataFrame and perform the selection and update.

import pandas as pd

df = pd.DataFrame({
    'city': ['NY', 'NY', 'NY', 'NY'],
    'sales': [100, 120, 90, 110],
    'returns': [5, 3, 4, 2]
}, index=['Q1', 'Q2', 'Q3', 'Q4'])

# 1) Select rows Q2..Q4 and only columns city, sales
# 2) Set sales at Q3 to 0 (use a scalar accessor)
# 3) Print the selection again
Hints
  • Use df.loc['Q2':'Q4', ['city', 'sales']]
  • Use df.at['Q3', 'sales'] = 0

Expected output (after the update):

    city  sales
Q2    NY    120
Q3    NY      0
Q4    NY    110
Show solution
result = df.loc['Q2':'Q4', ['city', 'sales']]
df.at['Q3', 'sales'] = 0
print(df.loc['Q2':'Q4', ['city', 'sales']])

Exercise 2 — Position-based slice and scalar edit

import pandas as pd

df2 = pd.DataFrame({
    'A': [10, 20, 30, 40],
    'B': [1, 2, 3, 4],
    'C': [7, 8, 9, 10]
}, index=[101, 102, 103, 104])

# 1) Print the first 3 rows and last 2 columns using .iloc
# 2) Multiply the scalar at row position 2, column position 0 by 10 using .iat
# 3) Print the first 3 rows to verify
Hints
  • df2.iloc[:3, -2:]
  • df2.iat[2, 0] = df2.iat[2, 0] * 10

Expected output (for the first 3 rows after update):

       A  B  C
101   10  1  7
102   20  2  8
103  300  3  9
Show solution
print(df2.iloc[:3, -2:])
df2.iat[2, 0] = df2.iat[2, 0] * 10
print(df2.iloc[:3])

Exercise checklist

  • You used .loc when selecting by labels and .iloc when selecting by positions
  • You used .at/.iat only for single scalars
  • Your slices behaved as expected: .loc inclusive, .iloc exclusive
  • No SettingWithCopy warnings appeared during assignments

Common mistakes and self-check

  • Mixing labels and positions together: df.loc[0:2, 0] is invalid; use .iloc for positions
  • Forgetting .loc is inclusive on label slices, accidentally including the end row
  • Chained indexing: df[df['x'] > 0]['y'] = 1 can lead to SettingWithCopy; prefer df.loc[df['x'] > 0, 'y'] = 1
  • Misspelled column names silently returning KeyError or empty results
  • Assuming index is sorted when slicing labels; if order matters, sort_index() first
Self-check mini test
  • Can you explain the difference between .loc and .iloc in one sentence?
  • Can you show one safe boolean filter with column selection using .loc?
  • Can you update one cell by label and by position?

Mini challenge

Given a DataFrame of monthly metrics indexed by month labels (e.g., '2024-01', '2024-02', ...), do the following:

  • Select months '2024-03' through '2024-06' and only columns ['visits', 'signups'] using .loc
  • Increase 'signups' in '2024-04' by 5 using a scalar accessor
  • Create a mask where conversion_rate >= 0.05 and set a new column 'tier' to 'A' for those rows using .loc assignment
Hint

Remember: label slice inclusive, and use df.at['2024-04', 'signups'] for single-cell update.

Who this is for

  • Aspiring and junior Data Analysts who use pandas for day-to-day analysis
  • Anyone cleaning, filtering, or reporting on tabular data in Python

Prerequisites

  • Basic Python syntax (lists, dicts, functions)
  • Intro to pandas: creating DataFrames, reading CSVs

Learning path

  • Start: Understand DataFrame/Series and indices
  • Then: Learn .loc and boolean filtering
  • Next: Learn .iloc for position-based slices
  • Optimize: Use .at/.iat for single-cell speed
  • Apply: Build a small cleaning pipeline using these indexers

Practical projects

  • Sales cleanup: Load monthly sales, select last quarter by labels, fix one bad entry with .at, and export
  • User segmentation: Filter active users with .loc mask, select just needed columns, and compute summary
  • QA audit: Randomly sample 100 rows using .iloc, then spot-correct individual cells with .iat

Next steps

  • Practice mixed row/column selection patterns until they feel natural
  • Refactor any chained indexing in your scripts to .loc assignments
  • Take the Quick Test below to confirm mastery. Available to everyone; sign in to save your progress.

Practice Exercises

2 exercises to complete

Instructions

Create the DataFrame and perform the selection and update.

import pandas as pd

df = pd.DataFrame({
    'city': ['NY', 'NY', 'NY', 'NY'],
    'sales': [100, 120, 90, 110],
    'returns': [5, 3, 4, 2]
}, index=['Q1', 'Q2', 'Q3', 'Q4'])

# 1) Select rows Q2..Q4 and only columns city, sales
# 2) Set sales at Q3 to 0 (use a scalar accessor)
# 3) Print the selection again
Expected Output
city sales Q2 NY 120 Q3 NY 0 Q4 NY 110

Indexing and Selection Loc Iloc At Iat — Quick Test

Test your knowledge with 10 questions. Pass with 70% or higher.

10 questions70% to pass

Have questions about Indexing and Selection Loc Iloc At Iat?

AI Assistant

Ask questions about this tool