Data AnalyticsPandas & NumPybeginner
Updated:

Pandas loc vs iloc: Selecting Data

4 min read

loc and iloc are how you precisely select rows and columns in pandas. Learn the difference between label-based and position-based indexing with examples.

TL;DR – Quick Answer

loc selects data by label, using the index and column names, while iloc selects by integer position, using numbers from 0. With loc the end of a slice is included; with iloc it is excluded, just like normal Python. Both take a rows selector and an optional columns selector separated by a comma. Choosing the right one for the job is a core pandas skill.

On This Page

Once your data is in a DataFrame, the very next skill is pulling out exactly the rows and columns you want. Pandas gives you two precise tools for this: loc and iloc. They look almost identical but answer different questions, and mixing them up is one of the most common early pandas bugs. This tutorial makes the distinction stick.

The one-line summary: loc selects by label (the index values and column names you can see), while iloc selects by integer position (counting from 0). Everything else follows from that single difference.

Setting up a sample DataFrame

To see labels clearly, we will use a meaningful index rather than the default 0, 1, 2. This is small illustrative sample data:

import pandas as pd

df = pd.DataFrame(
    {
        "city": ["Hyderabad", "Hyderabad", "Bengaluru", "Pune", "Bengaluru"],
        "age": [24, 31, 28, 45, 22],
        "salary": [48000, 65000, 52000, 90000, 47000],
    },
    index=["Aarti", "Bhaskar", "Chitra", "Devan", "Esha"],
)
print(df)
              city  age  salary
Aarti    Hyderabad   24   48000
Bhaskar  Hyderabad   31   65000
Chitra   Bengaluru   28   52000
Devan         Pune   45   90000
Esha     Bengaluru   22   47000

Now the row labels are names, which makes the label-versus-position difference obvious.

loc: selecting by label

loc uses the labels you see. Give it a row label to get that row as a Series:

print(df.loc["Chitra"])
city      Bengaluru
age              28
salary        52000
Name: Chitra, dtype: object

Add a comma and a column label to narrow to a single value, or pass lists to select several rows and columns:

print(df.loc["Chitra", "salary"])
print(df.loc[["Aarti", "Devan"], ["age", "salary"]])
52000
       age  salary
Aarti   24   48000
Devan   45   90000

A subtle but important rule: loc slices are inclusive of the endpoint. df.loc["Aarti":"Chitra"] returns Aarti, Bhaskar and Chitra, the endpoint included, which is different from normal Python slicing.

iloc: selecting by position

iloc ignores the labels entirely and counts positions from 0, exactly like list indexing:

print(df.iloc[2])            # third row
print(df.iloc[0, 1])         # first row, second column
print(df.iloc[0:2])          # first two rows, endpoint excluded
city      Bengaluru
age              28
salary        52000
Name: Chitra, dtype: object
24
              city  age  salary
Aarti    Hyderabad   24   48000
Bhaskar  Hyderabad   31   65000

Note the contrast with loc: df.iloc[0:2] returns two rows (positions 0 and 1), because iloc slicing excludes the endpoint like standard Python. This inclusive-versus-exclusive difference is the number one thing to remember.

iloc shines for positional jobs: df.iloc[:5] for the first five rows, df.iloc[-1] for the last row, df.iloc[:, -1] for the last column regardless of its name.

Selecting rows and columns together

Both accessors take the form [rows, columns]. The comma is what turns a one-dimensional selection into a two-dimensional one:

# label-based: matching rows, chosen columns
print(df.loc["Bhaskar":"Devan", ["age", "salary"]])
         age  salary
Bhaskar   31   65000
Chitra    28   52000
Devan     45   90000

To select all rows but only some columns, put a colon in the row slot: df.loc[:, ["age", "salary"]].

loc with conditions: the analyst's favourite

The most powerful use of loc combines a boolean condition for rows with a column list. This selects only the rows that satisfy a test, and optionally only the columns you want:

print(df.loc[df["salary"] > 50000, ["city", "salary"]])
              city  salary
Bhaskar  Hyderabad   65000
Chitra   Bengaluru   52000
Devan         Pune   90000

The condition df["salary"] > 50000 produces a boolean Series, and loc keeps the rows where it is True. This pattern is the bridge to full row filtering, covered in its own tutorial.

Practical usage

In day-to-day analysis, loc with a condition is how you isolate the slice of data a question is about: customers above a spend threshold, transactions in a date range, rows for one region. iloc is more of a utility, used to peek at the first or last few rows, grab a column by position when names are awkward, or step through data programmatically. Knowing which accessor fits keeps your code readable and correct.

Common mistakes

  • Using iloc with labels or loc with positions. df.iloc["Chitra"] raises an error because iloc wants an integer; df.loc[2] fails unless 2 is an actual index label. Match the accessor to what you are passing.
  • Forgetting the inclusive loc slice. df.loc[0:2] returns three rows, not two. If you expect Python-style exclusive slicing, use iloc.
  • Chained indexing for assignment. Writing df[df["age"] > 30]["salary"] = 0 may fail silently with a SettingWithCopyWarning. Use a single loc call instead: df.loc[df["age"] > 30, "salary"] = 0.
  • Dropping the comma. df.loc[["age"]] treats the list as row labels, not columns. To select columns you still need the row slot: df.loc[:, ["age"]].

In interviews

"What is the difference between loc and iloc?" is a near-guaranteed pandas question. The complete answer names three points: loc is label-based while iloc is position-based; loc slices include the endpoint while iloc slices exclude it; and both accept a rows-and-columns pair separated by a comma. Interviewers may hand you a DataFrame and ask you to select a specific subset, so practise translating a plain-English request into the right accessor. Mentioning the SettingWithCopyWarning and using df.loc[rows, cols] = value for assignment shows real depth.

Where this fits in your learning path

Precise selection is the skill that unlocks everything downstream in the data analytics path. It builds directly on the structures from Series and DataFrame and leads straight into filtering rows, where boolean conditions take centre stage. If you are just starting, revisit the pandas introduction first. Confident indexing is a baseline expectation for the data analyst role.

Frequently Asked Questions

What is the difference between loc and iloc in pandas?
loc selects by label, meaning it uses the actual index values and column names. iloc selects by integer position, counting from 0 regardless of the labels. Another difference is slicing: loc includes the end label while iloc excludes the end position, matching normal Python behaviour.
Does loc include the last element in a slice?
Yes. df.loc[0:2] returns rows with labels 0, 1 and 2, including the endpoint. This differs from standard Python and from iloc, where df.iloc[0:2] returns only positions 0 and 1. The inclusive endpoint is a frequent source of off-by-one confusion.
How do I select specific rows and columns at once?
Pass two selectors separated by a comma: df.loc[rows, columns] or df.iloc[rows, columns]. For example df.loc[df['age'] > 30, ['name', 'salary']] selects matching rows and only two columns. The comma is what makes it a two-dimensional selection.
Can I use loc with a boolean condition?
Yes, and it is one of loc's most powerful features. df.loc[df['salary'] > 50000] returns only the rows where the condition is True. You can add a column selector after a comma to also narrow the columns returned.
When should I use iloc instead of loc?
Use iloc when you care about position rather than label, such as grabbing the first five rows with df.iloc[:5] or the last column with df.iloc[:, -1]. Use loc when you want to select by meaningful index values or column names, which is more common in analysis.

Want to Build Your Career in Data Analytics with AI?

Join CodeBegun and train with working industry engineers — See the Data Analytics course in Hyderabad

Apply for Demo Class →
Siva Prasad Galaba
Founder, CodeBegun · Staff Engineer

Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaches Java, Spring Boot and system design the way the industry actually works, and mentors students through projects, mock interviews and placement preparation.

Technically reviewed by CodeBegun Technical TeamLast reviewed 16 July 2026 LinkedIn
Chat with us