Skip to content
Laviyx Learn

Try

Python for Data course menu

pandas loc vs iloc: Selecting Rows and Columns

Select data in pandas with loc (by label) and iloc (by position): single values, rows, columns, slices, lists, combining row and column selection, and how to avoid the SettingWithCopyWarning.

Beginner10 min readUpdated
On this page

pandas has two main selectors for DataFrames:

  • df.loc[rows, columns] selects by label (index values and column names);
  • df.iloc[rows, columns] selects by position (0, 1, 2, …).

Both take the rows first and the columns second, separated by a comma.

Python
import pandas as pd

df = pd.DataFrame({
    "dept":   ["Sales", "Engineering", "Engineering", "Marketing", "Sales"],
    "salary": [52000, 78000, 81000, 46000, 61000],
    "city":   ["Mumbai", "Bengaluru", "Pune", "Mumbai", "Delhi"],
}, index=["Asha", "Ravi", "Meera", "John", "Priya"])
print(df)
Output
              dept  salary       city
Asha         Sales   52000     Mumbai
Ravi   Engineering   78000  Bengaluru
Meera  Engineering   81000       Pune
John     Marketing   46000     Mumbai
Priya        Sales   61000      Delhi

The examples below use this DataFrame, with names as the index.

loc: by label#

Python
import pandas as pd

df = pd.DataFrame({
    "dept":   ["Sales", "Engineering", "Engineering", "Marketing", "Sales"],
    "salary": [52000, 78000, 81000, 46000, 61000],
    "city":   ["Mumbai", "Bengaluru", "Pune", "Mumbai", "Delhi"],
}, index=["Asha", "Ravi", "Meera", "John", "Priya"])

print(df.loc["Meera", "salary"])               # one value
print(df.loc["Ravi"])                          # one row, as a Series
print(df.loc[["Asha", "Priya"], ["dept", "city"]])
print(df.loc["Ravi":"John", "salary"])         # label slice: end included
print(df.loc[:, "salary":"city"])              # all rows, a range of columns
Output
81000
dept      Engineering
salary          78000
city        Bengaluru
Name: Ravi, dtype: object
        dept    city
Asha   Sales  Mumbai
Priya  Sales   Delhi
Ravi     78000
Meera    81000
John     46000
Name: salary, dtype: int64
       salary       city
Asha    52000     Mumbai
Ravi    78000  Bengaluru
Meera   81000       Pune
John    46000     Mumbai
Priya   61000      Delhi

iloc: by position#

Python
import pandas as pd

df = pd.DataFrame({
    "dept":   ["Sales", "Engineering", "Engineering", "Marketing", "Sales"],
    "salary": [52000, 78000, 81000, 46000, 61000],
    "city":   ["Mumbai", "Bengaluru", "Pune", "Mumbai", "Delhi"],
}, index=["Asha", "Ravi", "Meera", "John", "Priya"])

print(df.iloc[0])                 # first row
print(df.iloc[-1, 1])             # last row, second column
print(df.iloc[1:3, 0:2])          # position slice: end excluded
print(df.iloc[[0, 2, 4], [2]])    # chosen rows, chosen column
Output
dept       Sales
salary     52000
city      Mumbai
Name: Asha, dtype: object
61000
              dept  salary
Ravi   Engineering   78000
Meera  Engineering   81000
         city
Asha   Mumbai
Meera    Pune
Priya   Delhi

Selecting with conditions#

loc also accepts a boolean Series for the rows. This is the standard way to filter and pick columns in one step (more in Filtering Rows):

Python
import pandas as pd

df = pd.DataFrame({
    "dept":   ["Sales", "Engineering", "Engineering", "Marketing", "Sales"],
    "salary": [52000, 78000, 81000, 46000, 61000],
}, index=["Asha", "Ravi", "Meera", "John", "Priya"])

print(df.loc[df["salary"] > 60000, "dept"])
Output
Ravi     Engineering
Meera    Engineering
Priya          Sales
Name: dept, dtype: object

Changing values safely#

Use loc with both the rows and the column in one call to set values:

Python
import pandas as pd

df = pd.DataFrame({
    "dept":   ["Sales", "Engineering", "Marketing"],
    "salary": [52000, 78000, 46000],
}, index=["Asha", "Ravi", "John"])

df.loc[df["dept"] == "Sales", "salary"] += 5000      # raise for Sales only
df.loc["John", "dept"] = "Growth"
print(df)
Output
             dept  salary
Asha        Sales   57000
Ravi  Engineering   78000
John       Growth   46000

Writing df[df["dept"] == "Sales"]["salary"] = ... (two separate brackets) is chained assignment: the first step may create a copy, so the change is lost and pandas warns with SettingWithCopyWarning. One loc call with rows and column avoids the problem.

Fast single values: at and iat#

For reading or writing one value in a loop, at (label) and iat (position) are faster than loc/iloc:

Python
import pandas as pd

df = pd.DataFrame({"salary": [52000, 78000]}, index=["Asha", "Ravi"])
print(df.at["Ravi", "salary"], df.iat[0, 0])
Output
78000 52000

Common mistakes#

Practice#

Practice exercise

Using the employees DataFrame from this lesson (names as the index), print: (1) Priya's city, (2) the first three rows with only the salary column, (3) the departments of everyone in Mumbai, and (4) the DataFrame after giving everyone in Engineering a salary of at least 80000 (use .clip(lower=80000) on their salaries).

Show hint

(1) loc["Priya", "city"]; (2) iloc[:3] and the column position, or loc with .index[:3]; (3) a boolean condition in loc; (4) df.loc[cond, "salary"] = df.loc[cond, "salary"].clip(lower=80000).

Show solution
Python
import pandas as pd

df = pd.DataFrame({
    "dept":   ["Sales", "Engineering", "Engineering", "Marketing", "Sales"],
    "salary": [52000, 78000, 81000, 46000, 61000],
    "city":   ["Mumbai", "Bengaluru", "Pune", "Mumbai", "Delhi"],
}, index=["Asha", "Ravi", "Meera", "John", "Priya"])

print(df.loc["Priya", "city"])
print(df.iloc[:3, 1])
print(df.loc[df["city"] == "Mumbai", "dept"])
eng = df["dept"] == "Engineering"
df.loc[eng, "salary"] = df.loc[eng, "salary"].clip(lower=80000)
print(df)
Output
Delhi
Asha     52000
Ravi     78000
Meera    81000
Name: salary, dtype: int64
Asha        Sales
John    Marketing
Name: dept, dtype: object
              dept  salary       city
Asha         Sales   52000     Mumbai
Ravi   Engineering   80000  Bengaluru
Meera  Engineering   81000       Pune
John     Marketing   46000     Mumbai
Priya        Sales   61000      Delhi

Ravi's salary rose to 80000; Meera already earned more, so clip left her unchanged.

Key takeaway#

Next: Filtering Rows.

Finished this lesson?