pandas
python
data-analysis
get-column-index
dataframe-columns

Get column index from column name in python pandas

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

When working with pandas DataFrames, you sometimes need the integer position of a column rather than its label. This comes up when interfacing with NumPy arrays, slicing with iloc, or passing column indices to libraries that expect positional indexing. Pandas provides several ways to convert a column name to its positional index. This article covers the main approaches with code examples and explains when to use each one.

Setup

All examples use this sample DataFrame:

python
1import pandas as pd
2
3df = pd.DataFrame({
4    "name": ["Alice", "Bob", "Charlie"],
5    "age": [30, 25, 35],
6    "city": ["New York", "London", "Tokyo"],
7    "salary": [70000, 60000, 80000]
8})
9
10print(df.columns.tolist())
11# ['name', 'age', 'city', 'salary']

Method 1: get_loc()

The get_loc() method on the DataFrame's columns Index object is the most direct and efficient way to find a column's position.

python
index = df.columns.get_loc("city")
print(index)
# 2

get_loc() uses pandas' internal hash table for lookups, making it O(1) on average. It returns the integer position directly.

For a MultiIndex column structure, get_loc() returns a slice or boolean mask instead of a single integer:

python
1arrays = [["sales", "sales", "costs", "costs"],
2          ["Q1", "Q2", "Q1", "Q2"]]
3tuples = list(zip(*arrays))
4multi_cols = pd.MultiIndex.from_tuples(tuples)
5df_multi = pd.DataFrame([[1, 2, 3, 4]], columns=multi_cols)
6
7result = df_multi.columns.get_loc(("sales", "Q2"))
8print(result)
9# 1

Method 2: list.index()

Convert the columns to a list and use Python's built-in list.index() method.

python
index = df.columns.tolist().index("city")
print(index)
# 2

This is less efficient than get_loc() because it first creates a Python list (O(n) space) and then performs a linear search (O(n) time). For DataFrames with thousands of columns, the difference can be noticeable. For small DataFrames, both methods are effectively instant.

Method 3: Using NumPy's where()

If you need the indices of multiple columns at once, NumPy's where() or argwhere() can be useful.

python
1import numpy as np
2
3# Find index of a single column
4index = np.where(df.columns == "city")[0][0]
5print(index)
6# 2
7
8# Find indices of multiple columns
9cols_to_find = ["age", "salary"]
10indices = [np.where(df.columns == col)[0][0] for col in cols_to_find]
11print(indices)
12# [1, 3]

Method 4: get_indexer() for Multiple Columns

When you need positions for several column names at once, get_indexer() is the cleanest approach.

python
indices = df.columns.get_indexer(["age", "salary", "name"])
print(indices)
# [1 3 0]

get_indexer() returns a NumPy array of integer positions. If a column name is not found, the corresponding position is -1:

python
indices = df.columns.get_indexer(["age", "missing_col"])
print(indices)
# [ 1 -1]

This makes it easy to check for missing columns without catching exceptions.

Practical Use Cases

Using Column Index with iloc

python
1# Get the column index, then select that column by position
2col_idx = df.columns.get_loc("salary")
3salaries = df.iloc[:, col_idx]
4print(salaries.tolist())
5# [70000, 60000, 80000]

Reordering Columns by Position

python
1# Move "salary" to the second position
2cols = list(range(len(df.columns)))
3salary_idx = df.columns.get_loc("salary")
4cols.remove(salary_idx)
5cols.insert(1, salary_idx)
6
7df_reordered = df.iloc[:, cols]
8print(df_reordered.columns.tolist())
9# ['name', 'salary', 'age', 'city']

Interfacing with NumPy

python
1# Extract specific columns as a NumPy array using positional indices
2indices = df.columns.get_indexer(["age", "salary"])
3array = df.values[:, indices]
4print(array)
5# [[   30 70000]
6#  [   25 60000]
7#  [   35 80000]]

Conditional Column Selection

python
1# Find positions of all columns that contain numeric data
2numeric_indices = [
3    df.columns.get_loc(col)
4    for col in df.select_dtypes(include="number").columns
5]
6print(numeric_indices)
7# [1, 3]  (age and salary)

Handling Missing Columns

Both get_loc() and list.index() raise exceptions when the column name does not exist. Wrapping the call in a try-except block is the standard approach.

python
1def safe_get_loc(df, col_name):
2    """Return column index or -1 if the column does not exist."""
3    try:
4        return df.columns.get_loc(col_name)
5    except KeyError:
6        return -1
7
8print(safe_get_loc(df, "city"))      # 2
9print(safe_get_loc(df, "country"))   # -1

Alternatively, use get_indexer() which returns -1 for missing columns without raising an exception, as shown earlier.

Performance Comparison

For a DataFrame with 10,000 columns:

python
1big_df = pd.DataFrame({f"col_{i}": [0] for i in range(10000)})
2
3# get_loc: fastest (hash table lookup)
4%timeit big_df.columns.get_loc("col_9999")
5# Around 1-2 microseconds
6
7# list.index: slower (list conversion + linear search)
8%timeit big_df.columns.tolist().index("col_9999")
9# Around 200-500 microseconds
10
11# np.where: moderate (element-wise comparison)
12%timeit np.where(big_df.columns == "col_9999")[0][0]
13# Around 50-100 microseconds

For most real-world DataFrames (under a few hundred columns), all methods are fast enough. When column count is large or the lookup is inside a loop, prefer get_loc().

Common Pitfalls

  • Calling get_loc() on the DataFrame itself instead of on df.columns. The DataFrame does not have a get_loc method. Use df.columns.get_loc("name").
  • Assuming column indices are stable after adding or dropping columns. Any structural change to the DataFrame can shift column positions.
  • Using list.index() in a tight loop over many column names. Each call converts the columns to a list. Use get_indexer() with a list of names to do the lookup in one call.
  • Not handling KeyError when a column might not exist. This is especially important in data pipelines where upstream schema changes can remove columns.
  • Confusing get_loc() (which takes a single label) with get_indexer() (which takes a sequence of labels). Use the right one for your situation.

Summary

Use df.columns.get_loc("col_name") for the fastest single-column lookup. Use df.columns.get_indexer(["col_a", "col_b"]) when you need positions for multiple columns at once. Fall back to df.columns.tolist().index("col_name") only when you need pure Python and do not want to use pandas-specific methods. Always handle the case where a column name might not exist, either with try-except or by checking for -1 in the result of get_indexer().


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.