Question

Reorder DataFrame Columns in pandas: Move a Column to the Front

pythonpandasdataframesortingindexing

Question

Given the following pandas DataFrame:

import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.rand(10, 5))

After adding a row-wise mean column:

df["mean"] = df.mean(axis=1)

How can the mean column be moved to the first position while keeping all existing columns in their current relative order?

Short Answer

You will learn that a pandas DataFrame has an ordered list of column labels, and that changing the displayed column order means selecting or inserting columns in a new order. You will see how to move an existing column to the front and how to create it in the desired position from the start.

Concept

A pandas DataFrame stores data in named columns, and those columns have an order. When you assign a new column with:

df["mean"] = values

pandas normally appends it to the end of the DataFrame.

To change the order afterward, create a new column-label order and use it to select the DataFrame columns. This changes presentation and column-based operations without changing the values inside each row.

For a column that already exists, a reliable approach is:

df = df[["mean", *df.columns.drop("mean")]]

df.columns.drop("mean") produces every column except mean, preserving their original order. Putting "mean" first creates the required order.

Column order matters in practical work because it affects CSV exports, reports, notebook display, feature matrices, and code that expects columns in a particular sequence.

Mental Model

Think of DataFrame columns as labelled folders arranged on a shelf.

  • Assignment adds a new folder to the end of the shelf.
  • Reordering does not change the papers inside the folders.
  • It only changes where each folder sits.

To move mean to the front, take that folder out, place it first, and leave every other folder in the same order behind it.

Take Quiz

Syntax and Examples

To move an existing column named mean to the first position:

df = df[["mean", *df.columns.drop("mean")]]

Complete example:

import numpy as np
import pandas as pd

np.random.seed(1)
df = pd.DataFrame(np.random.rand(3, 3), columns=["a", "b", "c"])

df["mean"] = df.mean(axis=1)
df = df[["mean", *df.columns.drop("mean")]]

print(df)

The resulting column order is:

["mean", "a", "b", "c"]

An equally readable version uses a list comprehension:

df = df[["mean"] + [column for column in df.columns if column != "mean"]]

Both versions preserve the relative order of all non-mean columns.

Step by Step Execution

Consider this DataFrame:

import pandas as pd

df = pd.DataFrame({
    "a": [2, 4],
    "b": [6, 8],
    "c": [10, 12]
})

df["mean"] = df.mean(axis=1)
df = df[["mean", *df.columns.drop("mean")]]

Step by step:

  1. Initially, df.columns is Index(['a', 'b', 'c']).
  2. df.mean(axis=1) calculates each row's mean. axis=1 means “calculate across columns.”
  3. Assignment creates the new column at the end. The order becomes ['a', 'b', 'c', 'mean'].
  4. df.columns.drop('mean') returns ['a', 'b', 'c'].
  5. ['mean', *df.columns.drop('mean')] creates ['mean', 'a', 'b', 'c'].
  6. df[...] selects columns in that exact order, and the result is assigned back to df.

The values remain associated with their original column labels; only the column sequence changes.

Real World Use Cases

Common reasons to put a column first include:

  • Reports: Put an identifier such as customer_id, order_id, or date before measurements.
  • Data exports: Ensure important fields appear first when writing a CSV for another team or system.
  • Machine learning datasets: Put a target column such as label or is_fraud in a predictable location for inspection or a downstream tool.
  • Analytics notebooks: Place derived summary columns, such as mean, total, or status, where readers see them immediately.
  • APIs and database extracts: Arrange fields consistently before serializing records or showing them in a table.
Take Quiz

Real Codebase Usage

In production code, developers often prefer to set the intended order at the point where a column is created.

Use insert when adding a new column at a known position:

df.insert(0, "mean", df.mean(axis=1))

insert(0, ...) means insert at integer position 0, the first column. This avoids appending and then reordering.

When the column may already exist, reorder explicitly after validation:

required_column = "mean"

if required_column not in df.columns:
    raise KeyError(f"Missing expected column: {required_column}")

df = df[[required_column, *df.columns.drop(required_column)]]

For a fixed export schema, teams commonly declare the complete order in one place:

export_columns = ["customer_id", "mean", "a", "b", "c"]
df = df.reindex(columns=export_columns)

Use a fixed schema only when the listed columns are genuinely expected. reindex can create missing columns filled with NaN, which may or may not be desirable.

Common Mistakes

Using axis=0 for a row-wise mean

This calculates one mean per column, not one mean per row:

# Not a row-wise mean
df["mean"] = df.mean(axis=0)

Use axis=1 for a mean across the columns in each row:

df["mean"] = df.mean(axis=1)

Selecting only the moved column

This removes all other columns from the result:

# Keeps only one column
df = df[["mean"]]

Include mean plus the remaining labels:

df = df[["mean", *df.columns.drop("mean")]]

Forgetting to save the reordered DataFrame

Column selection returns a DataFrame:

df[["mean", *df.columns.drop("mean")]]  # Result is not stored

Assign it back when you want df itself to use the new order:

df = df[["mean", *df.columns.drop("mean")]]

Calling insert after the column was already assigned

By default, insert does not allow a duplicate label:

df["mean"] = df.mean(axis=1)
df.insert(0, "mean", df.mean(axis=1))  # Raises ValueError

Choose one approach: use insert initially, or assign first and then reorder.

Confusing column labels with positions

The original DataFrame created from NumPy has integer labels 0, 1, 2, and so on. They are labels, not necessarily positions. Prefer label-based operations such as df.columns.drop("mean") when reordering by name.

Comparisons

ApproachBest whenExampleNotes
Select columns in a new orderThe column already existsdf = df[["mean", *df.columns.drop("mean")]]Clear and preserves the other order.
DataFrame.insertYou are creating the column nowdf.insert(0, "mean", values)Avoids a separate reorder operation.
DataFrame.pop plus insertYou want to explicitly remove and reinsert an existing columndf.insert(0, "mean", df.pop("mean"))Mutates the DataFrame in place.
reindex(columns=...)You have a complete, declared schemadf = df.reindex(columns=order)Missing labels become new NaN columns.

pop is useful for an existing column:

df.insert(0, "mean", df.pop("mean"))

It removes mean, returns its values as a Series, and inserts it at position 0.

Take Quiz

Cheat Sheet

# Add a row-wise mean column at the end
df["mean"] = df.mean(axis=1)

# Move an existing column to the front
df = df[["mean", *df.columns.drop("mean")]]

# Add the column directly at the front
df.insert(0, "mean", df.mean(axis=1))

# Move an existing column in place
df.insert(0, "mean", df.pop("mean"))

# Move a column to position 2 (third position)
column = "mean"
df.insert(2, column, df.pop(column))

# Use a fully specified order
order = ["mean", "a", "b", "c"]
df = df.reindex(columns=order)

Rules to remember:

  • axis=1 means calculate across columns for each row.
  • Assigning with df["name"] = ... appends a new column.
  • insert(position, name, values) places a new column at a specific position.
  • Reorder an existing column by selecting an explicit list of labels or by using pop and insert.

FAQ

Does changing DataFrame column order change the data?

No. It changes only the sequence in which columns appear. The values remain in their respective labelled columns.

How do I move a pandas column to the first position?

For an existing column named mean:

df = df[["mean", *df.columns.drop("mean")]]

Can I add a column directly at the beginning?

Yes. Use insert before the column exists:

df.insert(0, "mean", df.mean(axis=1))

Why is axis=1 used with df.mean()?

axis=1 calculates one result per row by averaging values across that row's columns. axis=0 calculates one result per column.

Does df.insert() modify the DataFrame in place?

Yes. insert changes the existing DataFrame and returns None.

What happens if I use reindex with a missing column name?

pandas creates that column and fills it with missing values (NaN). Use direct column selection instead if missing columns should cause an error.

Can columns have integer names?

Yes. In pd.DataFrame(np.random.rand(10, 5)), the initial labels are integers from 0 through 4.

Take Quiz

Mini Project

Description

Build a small score-report DataFrame. Calculate each student's average score, then place the derived average column first so the report is easy to scan and exports in a useful order.

Goal

Create a student score report with average as its first column while preserving the order of the original score columns.

Requirements

Create a DataFrame with student names and at least three numeric subject-score columns. Calculate a row-wise average from the subject-score columns. Add the derived column with the name average. Move average to the first column position. Print the completed report.

Take Quiz

Keep learning

Related questions

View more