loc vs iloc
df.loc[rows, cols] selects by label (index values and column names) and df.iloc[rows, cols] selects by integer position, counting from 0. A loc slice includes its end label; an iloc slice excludes its end position, like a Python list.
Syntax
df.loc[row_labels, column_labels] | df.iloc[row_positions, column_positions]| Part | What it is |
|---|---|
row_labels / row_positions | A single value, a list, a slice or a boolean array |
column_labels / column_positions | Optional; omit to keep all columns |
Examples
import pandas as pd
df = pd.DataFrame(
{"name": ["Ana", "Ben", "Cara", "Dan"],
"dept": ["Sales", "IT", "Sales", "HR"],
"salary": [50000, 62000, 58000, 45000]},
index=["a", "b", "c", "d"])
print(df.loc["b", "salary"])Result: 62000
df.loc["a":"c", ["name", "salary"]]Result: name salary a Ana 50000 b Ben 62000 c Cara 58000
The label slice a:c includes c.
df.iloc[0:2, 0:2]Result: name dept a Ana Sales b Ben IT
Positions 0 and 1 only; the end of an iloc slice is excluded.
Common mistakes
- KeyError with iloc-style numbers in loc: df.loc[0] looks for the label 0, which does not exist when the index is strings or dates; use df.iloc[0] for the first row.
- Off-by-one results from slicing: df.loc[0:3] returns four rows (labels 0 to 3 inclusive) while df.iloc[0:3] returns three.
- SettingWithCopyWarning when assigning with chained indexing like df[df.x > 1]["y"] = 0; assign with a single df.loc[df.x > 1, "y"] = 0 instead.
Practice loc vs iloc
These drills check your answer on live data, free, no account needed.
- Rows and columns with locUse `.loc` to select the employees in the Engineering department, keeping only the `name` and `years` columns (in that order).
- Position-based slicing with ilocReturn the first three rows and the first two columns of `emp`, selected by position with `.iloc`.
Questions
Which is faster, loc or iloc?
iloc is slightly faster because it skips label lookup, but the difference only matters inside tight loops. Pick the one that matches what you know: labels or positions.
How do I get the last row?
df.iloc[-1] returns the last row by position regardless of the index labels. df.tail(1) returns it as a one-row DataFrame.
What is df.at and df.iat?
They are fast scalar versions of loc and iloc for a single cell: df.at["b", "salary"] and df.iat[1, 2].
Related
- Filter rowsHow to filter rows in a pandas DataFrame by one or several conditions using boolean masks, with the & | ~ operators, parentheses, isin, between and query.
- set_index and reset_indexHow to use set_index and reset_index in pandas: make a column the row index, go back to a plain column, drop the index, and flatten a groupby result.
- head, tail and sampleHow to look at a pandas DataFrame with head, tail and sample: the first or last N rows, random rows with a seed, a fraction of rows, and showing all rows.
- DataFrame.queryHow df.query works in pandas: conditions as a string with and, or, not, in, variables with @, column names with spaces, and when to use boolean masks instead.