Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsUse .loc when you mean an index or column label; use .iloc when you mean a zero-based position. An integer passed to .loc is still a label, not a position. For example, df.loc[0] selects the row labeled 0, while df.iloc[0] selects the first row.
What is the difference between .loc and .iloc?
The difference is what your selector refers to: .loc looks up labels, and .iloc counts positions from zero. Consider this DataFrame, whose row labels are letters:
As an Amazon Associate I earn from qualifying purchases.
import pandas as pd
df = pd.DataFrame(
{"name": ["Ada", "Linus", "Grace"], "score": [98, 91, 95]},
index=["a", "b", "c"]
)
df.loc["b"] returns the row labeled b (Linus). df.iloc[1] returns the row at position 1, which is also Linus in this example. They happen to reach the same row, but they use different rules.
The current stable pandas indexing guide describes .loc as primarily label-based. See the pandas indexing guide.
#1 Best Overall
Why an integer index causes confusion
A DataFrame’s default index is usually 0, 1, 2, …. With that index, df.loc[0] appears to mean “first row” because the first row’s label is 0. It actually means “row whose label is 0.” If rows are reordered or the index is changed, the label and position may no longer match.
Use .iloc[0] when you specifically mean the first row, regardless of its label. Use .loc[0] when you specifically mean the row labeled 0.
Rank #2
How do .loc and .iloc slices differ?
.loc includes the stop label when that label is present. .iloc follows ordinary Python slicing: it includes the start position and excludes the stop position.
df.loc["a":"b"] # rows labeled "a" and "b"
df.iloc[0:2] # positions 0 and 1
Here both expressions return the first two rows, but for different reasons. With .iloc, the stop value 2 is not included; with .loc, the endpoint label "b" is included.
How do you select rows and columns together?
Use a comma to separate the row selector from the column selector. Both selectors must follow the accessor’s convention:
df.loc["b", "score"] # row label "b", column label "score"
df.iloc[1, 1] # second row, second column
df.loc["a":"b", ["name", "score"]]
df.iloc[0:2, 0:2]
The same rule applies to Series: .loc selects by the Series index labels, while .iloc selects by position.
What errors and boolean selectors should you expect?
- Missing label: requesting a label that is not present with
.locraisesKeyError. - Out-of-bounds position: an integer position outside the axis bounds passed to
.ilocraisesIndexError. Slice indexers can extend beyond the axis bounds under Python/NumPy slice behavior. - Boolean Series:
.loccan use an index-aligned boolean Series, so its values are matched by index..ilocexpects a boolean array rather than an index-aligned Series; pass the values when you want array-style positional filtering. - Boolean arrays: both accessors accept boolean arrays. The pandas indexing guide says missing values in boolean arrays are treated as false.
For example, if mask is a boolean Series aligned to df, use df.loc[mask]. To give .iloc the boolean values as an array, use df.iloc[mask.to_numpy()].
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Quick Recap
Best Value
Which accessor should you choose?
- Choose
.locwhen your code should keep referring to named rows or columns, even if their order changes. - Choose
.ilocwhen your code should select a particular place in the current row or column order.
Memory aid: labels → .loc; positions → .iloc.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




