0Pricing
Pandas & NumPy Academy · Lesson

Sorting by Index

Reorder rows by their index label with sort_index() and understand when a sorted index improves performance.

Sorting by Index is a free Pandas & NumPy Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Pandas & NumPy Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Understanding the DataFrame Index

Every Pandas DataFrame has a row index — a set of labels used to identify and access rows. By default, this is a RangeIndex (0, 1, 2, …), but you can set it to any column (dates, names, IDs) using set_index(). When the index is meaningful (e.g., a DatetimeIndex or a customer ID), sorting by it rather than by a column value produces a logically organised output.

import pandas as pd

df = pd.DataFrame(
    {'value': [10, 20, 30]},
    index=['C', 'A', 'B']  # out-of-order alphabetic index
)
print(df)
#    value
# C     10
# A     20
# B     30

sort_index() — Ascending

DataFrame.sort_index() reorders rows by their index label rather than by column values. By default, sorting is ascending — alphabetically for string indices, numerically for integer indices, and chronologically for DatetimeIndex. This is the standard way to restore a dataset to a natural order after shuffling or appending records out of sequence.

import pandas as pd

df = pd.DataFrame(
    {'temp': [22.5, 19.0, 25.1, 18.3]},
    index=pd.to_datetime(['2024-03-01', '2024-01-15', '2024-06-10', '2024-01-01'])
)

sorted_df = df.sort_index()
print(sorted_df)
#             temp
# 2024-01-01  18.3
# 2024-01-15  19.0
# 2024-03-01  22.5
# 2024-06-10  25.1

sort_index() Descending

Pass ascending=False to sort the index from largest (or latest) to smallest (or earliest). For a DatetimeIndex this puts the most recent observations at the top, which is the typical layout for financial data, log files, and event streams where the latest event is most relevant.

import pandas as pd

df = pd.DataFrame(
    {'price': [100, 110, 105, 115]},
    index=pd.to_datetime(['2024-01', '2024-02', '2024-03', '2024-04'])
)

# Most recent first
print(df.sort_index(ascending=False))
#             price
# 2024-04-30    115
# 2024-03-31    105
# 2024-02-29    110
# 2024-01-31    100

Sorting Column Labels with axis=1

By default, sort_index() sorts the row index (axis=0). Pass axis=1 to sort the column labels alphabetically instead. This is useful for standardising wide DataFrames with many columns so columns appear in a predictable alphabetical order, making it easier to visually find a column or compare DataFrames.

import pandas as pd

df = pd.DataFrame({
    'zebra': [1], 'apple': [2], 'mango': [3], 'banana': [4]
})

print('Before:', df.columns.tolist())
# ['zebra', 'apple', 'mango', 'banana']

sorted_cols = df.sort_index(axis=1)
print('After:', sorted_cols.columns.tolist())
# ['apple', 'banana', 'mango', 'zebra']

When is a Sorted Index Faster?

Pandas can use binary search for label look-ups when the index is sorted (monotonic). A sorted index makes .loc['2024-01':'2024-06'] slices O(log n) instead of O(n). The method is_monotonic_increasing (or is_monotonic_decreasing) returns a boolean indicating whether the index is already sorted. Sorting a large index before slicing repeatedly is a worthwhile one-time cost.

import pandas as pd
import numpy as np

idx = pd.to_datetime(['2024-03-01', '2024-01-15', '2024-06-10'])
df = pd.DataFrame({'v': [1, 2, 3]}, index=idx)

print('Sorted?', df.index.is_monotonic_increasing)  # False

df = df.sort_index()
print('Sorted?', df.index.is_monotonic_increasing)  # True

# Now slicing is efficient
print(df.loc['2024-01':'2024-03'])

sort_index() with MultiIndex

When a DataFrame has a MultiIndex (hierarchical row index), sort_index() sorts all levels in the hierarchy by default. You can restrict sorting to specific levels with the level parameter. A sorted MultiIndex is required for efficient hierarchical slicing with .loc[(outer, inner), :].

import pandas as pd

arrays = [
    ['B', 'B', 'A', 'A'],
    ['two', 'one', 'two', 'one']
]
idx = pd.MultiIndex.from_arrays(arrays, names=['first', 'second'])
df = pd.DataFrame({'value': [10, 20, 30, 40]}, index=idx)

print(df.sort_index())
#               value
# first second
# A     one       40
#       two       30
# B     one       20
#       two       10

Sorting Only One Level of MultiIndex

With a MultiIndex, you may want to sort on only the inner or outer level while keeping the other level's order intact. Pass level= to sort_index() — it accepts an integer (level position), a string (level name), or a list. This is useful when the outer level order is already correct and you only need to sort within each group.

import pandas as pd

df = pd.DataFrame({
    'sales': [300, 100, 200, 400, 150, 250]
}, index=pd.MultiIndex.from_tuples([
    ('Eng', 'Dave'), ('Eng', 'Alice'), ('Eng', 'Bob'),
    ('HR', 'Zoe'), ('HR', 'Carol'), ('HR', 'Eve')
], names=['dept', 'name']))

# Sort only the 'name' level alphabetically within each dept
print(df.sort_index(level='name'))
#              sales
# dept name
# Eng  Alice    100
#      Bob      200
#      Dave     300
# HR   Carol    150
#      Eve      250
#      Zoe      400

Difference Between sort_index() and sort_values()

It is important to distinguish the two sort methods. sort_values(by='col') reorders rows based on the data values in a column. sort_index() reorders rows based on the row label (the index), which may or may not correspond to any column. When the index is the primary identifier (e.g., a DatetimeIndex or a meaningful string key), sort_index() is the right choice.

import pandas as pd

df = pd.DataFrame(
    {'value': [30, 10, 20]},
    index=['C', 'A', 'B']
)

# sort_index: sorted by row label A, B, C
print(df.sort_index())
#    value
# A     10
# B     20
# C     30

# sort_values: sorted by data value 10, 20, 30
print(df.sort_values('value'))
#    value
# A     10
# B     20
# C     30
# (same here because values happen to match alphabetical label order!)

Restoring Original Order After Ops

Some operations (shuffling, random sampling with df.sample(frac=1)) scramble the row order. sort_index() is the clean way to restore the original sequential order. If the original order was a RangeIndex (0, 1, 2, …), sort_index() restores it; if it was a meaningful label, it restores that label's natural ordering.

import pandas as pd

df = pd.DataFrame({'x': [10, 20, 30, 40, 50]})

# Shuffle (random sample)
shuffled = df.sample(frac=1, random_state=42)
print('Shuffled index:', shuffled.index.tolist())
# e.g. [2, 4, 0, 1, 3]

# Restore original order by sorting the index
restored = shuffled.sort_index()
print('Restored index:', restored.index.tolist())
# [0, 1, 2, 3, 4]

sort_index() with na_position

Like sort_values(), sort_index() also supports na_position for controlling where NaN index labels appear. This matters when a DataFrame has a string or date index that contains some NaN labels (possible after operations that introduce missing index values). The default is 'last'.

import pandas as pd
import numpy as np

df = pd.DataFrame(
    {'v': [1, 2, 3, 4]},
    index=['B', None, 'A', 'C']
)

print(df.sort_index(na_position='last'))
#      v
# A    3
# B    1
# C    4
# NaN  2

Performance Gain Measurement

You can empirically measure the performance benefit of a sorted index by using Python's timeit to compare a slice on an unsorted vs. sorted DatetimeIndex. The sorted case uses binary search and is typically 5-20x faster for large DataFrames. This demonstrates why sort_index() is not just a cosmetic operation — it has real runtime implications.

import pandas as pd
import numpy as np

np.random.seed(0)
random_dates = pd.to_datetime(
    pd.Timestamp('2020-01-01').value + np.random.randint(0, 1_000_000_000_000_000, size=100_000),
    unit='ns'
)
df = pd.DataFrame({'val': np.random.randn(100_000)}, index=random_dates)

# Without sort: O(n) scan
import timeit
t1 = timeit.timeit(lambda: df.loc['2022-01':'2022-06'], number=100)

df_sorted = df.sort_index()
t2 = timeit.timeit(lambda: df_sorted.loc['2022-01':'2022-06'], number=100)

print(f'Unsorted: {t1:.3f}s, Sorted: {t2:.3f}s, Speedup: {t1/t2:.1f}x')

Quick Check

Test your understanding of sorting by index in Pandas.

Lesson Recap

In this lesson you learned: sort_index() reorders rows by their label (not column values), axis=1 sorts column labels alphabetically, and a sorted index enables binary search making time-based slicing much faster. For MultiIndex DataFrames, level= restricts sorting to one hierarchy level. Always check is_monotonic_increasing before relying on efficient slice lookups. Next up we rank values within a column.

Frequently asked questions

Is the “Sorting by Index” lesson free?

Yes — the full text of “Sorting by Index” is free to read here on the web, and the Pandas & NumPy Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Pandas & NumPy Academy course, upgrade to CoddyKit PRO.

What will I learn in “Sorting by Index”?

Reorder rows by their index label with sort_index() and understand when a sorted index improves performance. You practise Pandas & NumPy Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Pandas & NumPy Academy?

No prior experience is required. Pandas & NumPy Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Sorting by Index” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Pandas & NumPy Academy lesson?

Yes. Every Pandas & NumPy Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Sorting by Column Values
  2. Sorting by Index
  3. Ranking Values
  4. Setting and Resetting the Index
← Back to Pandas & NumPy Academy