data-science

Difference Between loc and iloc in pandas: Verified Guide

In pandas, selecting subsets of a DataFrame correctly requires understanding the difference between loc and iloc: loc is label-based and includes the endpoint, while iloc is pos...

Mara Ellison
Difference Between loc and iloc in pandas: Verified Guide

In pandas, selecting subsets of a DataFrame correctly requires understanding the difference between loc and iloc: loc is label-based and includes the endpoint, while iloc is position-based and excludes the endpoint. This evergreen explainer defines each operator, shows concrete examples, common pitfalls, and performance-aware patterns so you can choose the right accessor for real workflows. Topics covered include indexing rules, slicing behavior with integers and strings, setting values, and comparisons that reduce ambiguity in day-to-day analysis.

What loc and iloc Do in pandas

pandas provides two primary indexers for selecting rows and columns: loc and iloc. The difference between loc and iloc in pandas centers on how they interpret arguments. loc uses labels, meaning you reference rows and columns by their index and column labels inclusively. iloc uses integer positions, meaning you reference rows and columns by their numerical place starting at 0, with the endpoint excluded. Choosing the correct indexer prevents subtle misselections and keeps your code predictable across data with non-default indexes.

Label-Based Selection with loc

The loc indexer enables label-based selection. When you use loc, you refer to the actual index and column labels present in the DataFrame or Series. Slicing with loc is inclusive on both ends for labels. If your index is a default integer index, loc will still treat those integers as labels rather than positions, which is important to avoid confusion. This behavior is consistent whether you are selecting rows, columns, or both.

Syntax and Rules for loc

loc supports multiple patterns: selecting by single label, lists of labels, slices of labels, and boolean arrays. When slicing with loc, the stop value is included, similar to plain Python slicing on a list of labels. Columns can be selected by passing a column label or a list of column labels. Here are common usage patterns with loc:

  • df.loc[row_label] returns one row as a Series.
  • df.loc[row_label, column_label] returns a scalar value.
  • df.loc[row_slice, column_list] returns a subset DataFrame.
  • df.loc[boolean_series] filters rows where the condition is True.

Examples of loc Usage

Consider a DataFrame with a named index and columns such as Name and Score. Using df.loc[2, 'Score'] returns the value in row with index label 2 and column Score. With a slice like df.loc[1:3, ['Name', 'Score']], both endpoint labels 1 and 3 are included. Boolean selection such as df.loc[df['Score'] > 70] returns all rows where Score exceeds 70. These patterns work reliably as long as the labels exist in the index and columns.

Position-Based Selection with iloc

The iloc indexer enables position-based selection. iloc refers to integer positions starting from 0, ignoring the actual index labels. Slicing with iloc excludes the endpoint, following standard Python semantics. This is useful when you care about the nth row or column regardless of its label. iloc behaves similarly across pandas objects with any index type, because it only considers positional order.

Syntax and Rules for iloc

iloc accepts integer-based indexing for rows and columns. It supports single integers, lists of integers, slices of integers, and arrays of booleans. Key behaviors include:

  • df.iloc[row_position] returns one row as a Series by position.
  • df.iloc[row_position, col_position] returns a scalar value.
  • df.iloc[row_slice, col_slice] returns a subset DataFrame.
  • df.iloc[boolean_array] filters rows by a boolean condition array.

Examples of iloc Usage

Using iloc, df.iloc[0, 1] selects the first row and second column by position, not by label. A slice such as df.iloc[1:4, 0:2] selects rows at positions 1 through 3 and columns at positions 0 through 1, excluding position 4. Boolean patterns like df.iloc[df['Score'] > 60] are not directly supported; you must convert the boolean Series to a position array using numpy or .values where needed. These rules make iloc predictable when index labels are non-integer or non-sequential.

Key Behavioral Differences Between loc and iloc

Understanding the core behavioral differences reduces mistakes when selecting and updating data. loc is label-based and inclusive of slice endpoints; iloc is position-based and exclusive of slice endpoints. With integer-labeled indexes, it is possible to write syntactically similar code that produces different results. Setting values uses the same selection patterns but assigns new data. Below is a compact comparison of essential attributes to highlight contrasts.

Quick Comparison of loc and iloc

Attributelociloc
Indexing TypeLabel-basedPosition-based
Slice EndpointIncludedExcluded
Argument TypeLabels (can be ints, strings)Integers only
Out-of-BoundsRaises KeyError if label missingRaises IndexError if position missing
With Default RangeIndexdf.loc[2] refers to label 2df.iloc[2] refers to position 2

Practical Considerations and Common Pitfalls

Many subtle issues arise from mixing loc and iloc, especially with DataFrames that have integer indexes or non-sequential rows. Because loc includes the endpoint, slicing with loc can return more rows than expected if you are used to iloc behavior. Conversely, iloc excludes the endpoint, which may surprise users expecting label-inclusive slicing. Another common pitfall is using boolean conditions incorrectly: loc accepts boolean Series directly, while iloc requires positional boolean arrays. Always verify the index and column labels before chaining selections, and consider using .iloc when working with row numbers rather than identifiers.

Performance and Use-Case Guidance

Both loc and iloc are optimized for typical selection tasks, but patterns can matter at scale. Prefer loc when your workflow is tied to meaningful labels, such as dates, IDs, or named rows. Use iloc when you need exact positions, such as iterating over fixed columns by rank or working with numeric indices detached from label semantics. For large DataFrames, avoiding chained indexing and using these accessors with a single call reduces ambiguity and improves clarity. Choosing the right indexer consistently makes scripts more maintainable and reduces hidden errors in data pipelines.

Related Reading

More pages in this topic cluster.

How to Get Rows from a DataFrame: Methods and Best Practices

Getting rows of a DataFrame is a core operation in data analysis in Python, typically using pandas. You can retrieve rows by position, label, condition, or a combination of thes...

Read next
Sensitivity and Specificity Analysis to Reach Optimization

Sensitivity and specificity analysis is a disciplined way to appraise how well a binary classifier or diagnostic test identifies true positives and true negatives, and to use th...

Read next
Andaconda Plan: Definition, Purpose, and Practical Use in Data Science

The Andaconda Plan refers to a specialized Python and R distribution designed for data science, analytics, and scientific computing. It bundles commonly used libraries, package...

Read next