PD-01-012-P · Primer — Sorting Data
The idea in one sentence
Sorting reorders the rows of a DataFrame so the values in one or more columns run in a chosen order — smallest to largest, largest to smallest, or A to Z.
Why it exists
Raw data almost never arrives in the order you want to read it. A spreadsheet of orders comes in the sequence they happened to be typed; a table of players comes in whatever order the file was written. But humans and reports think in ranked terms: "top five scores," "newest first," "alphabetical by name." sort_values is the tool that turns an arbitrary pile of rows into a meaningful sequence, and it does so without you writing a single loop or comparison. Once your data is sorted, everything downstream — the first row, the last row, the head of a chart — carries meaning.
How it works
Call df.sort_values('column') and pandas returns a new DataFrame with the rows arranged so that column runs from smallest to largest (ascending, the default). Pass ascending=False to flip it to largest-first. To break ties, hand sort_values a list of columns: pandas sorts by the first, and only within groups of equal values does it look at the second, and so on. You can even give a matching list of booleans to ascending so each key gets its own direction. Notice the original row labels (the numbers in the leftmost column below) travel along with their rows — sorting rearranges rows, it does not renumber them.
import pandas as pd
df = pd.DataFrame({
'name': ['Ana', 'Ben', 'Cara', 'Dan'],
'team': ['Blue', 'Red', 'Blue', 'Red'],
'score': [88, 72, 88, 95],
})
# Sort by score, highest first
print(df.sort_values('score', ascending=False))
# name team score
# 3 Dan Red 95
# 0 Ana Blue 88
# 2 Cara Blue 88
# 1 Ben Red 72
# Sort by team (A-Z), then score (high to low) within each team
print(df.sort_values(['team', 'score'], ascending=[True, False]))
# name team score
# 0 Ana Blue 88
# 2 Cara Blue 88
# 3 Dan Red 95
# 1 Ben Red 72
The one gotcha
sort_values returns a sorted copy — it does not change df in place. If you write df.sort_values('score') on its own line and then keep using df, your data is exactly as unsorted as before. Either capture the result (df = df.sort_values('score')) or, if you truly want to mutate the original, pass inplace=True. A close cousin is sort_index, which reorders rows by their labels instead of a column's values — handy for restoring the original order after a sort, since those labels came along for the ride.
See it — one column becomes an ordered sequence
flowchart LR
A["Unsorted rows<br/>score: 88, 72, 88, 95"] --> B["sort_values('score',<br/>ascending=False)"]
B --> C["Ordered rows<br/>score: 95, 88, 88, 72"]
C --> D["Ties broken by<br/>2nd key if given"]
The one-line takeaway
df.sort_values(cols, ascending=...) returns a reordered copy — pass a list of columns for tie-breaking, and remember to reassign the result.
Where you'll meet it
Ranking leaderboards and "top-N" reports, ordering time series so the newest (or oldest) entry sits first, arranging tables alphabetically before you export them, and setting up data so .head() or a plotted line reads in a sensible direction. Nearly every polished report ends with a sort.
Named concepts: sort_values, ascending/descending, multi-key sort, sort_index
