Lesson 14
Sorting Data
Order a Series or a DataFrame by its values or by its index, sort on several columns at once, and grab the top rows with nlargest.
sort_values orders by what is in the cells and sort_index orders by the labels. Both return a new object and both carry the index along, so a row keeps its label wherever it lands.
Sort a Series
sort_values on a Series orders the values and drags the labels with them. sort_index puts the labels back in order, which is how you undo a value sort.
import pandas as pd
sales = pd.Series([120, 85, 140, 95], index=["Mon", "Tue", "Wed", "Thu"])
print(sales.sort_values())
print(sales.sort_values(ascending=False))
print(sales.sort_index())Output:
Tue 85
Thu 95
Mon 120
Wed 140
dtype: int64
Wed 140
Mon 120
Thu 95
Tue 85
dtype: int64
Mon 120
Thu 95
Tue 85
Wed 140
dtype: int64Sort a DataFrame
Name the column to sort by. ascending=False gives largest first. The index comes along, so reset_index(drop=True) is what you want if the old numbers only cause confusion.
import pandas as pd
learners = pd.DataFrame({
"name": ["Avery", "Jordan", "Casey", "Riley", "Morgan", "Quinn"],
"track": ["Python", "NumPy", "Python", "pandas", "NumPy", "pandas"],
"city": ["Northgate", "Eastport", "Northgate", "Westfield", "Eastport", "Westfield"],
"hours": [42, 31, 55, 24, 47, 38],
"score": [88, 74, 91, 65, 82, 79],
})
print(learners.sort_values("score", ascending=False)[["name", "score"]])
print(learners.sort_values("hours").reset_index(drop=True)[["name", "hours"]])Output:
name score
2 Casey 91
0 Avery 88
4 Morgan 82
5 Quinn 79
1 Jordan 74
3 Riley 65
name hours
0 Riley 24
1 Jordan 31
2 Quinn 38
3 Avery 42
4 Morgan 47
5 Casey 55Several columns at once
A list of names sorts by the first, then breaks ties with the second. ascending can be a list too, one value per column, so you can sort a group ascending and its scores descending.
import pandas as pd
learners = pd.DataFrame({
"name": ["Avery", "Jordan", "Casey", "Riley", "Morgan", "Quinn"],
"track": ["Python", "NumPy", "Python", "pandas", "NumPy", "pandas"],
"city": ["Northgate", "Eastport", "Northgate", "Westfield", "Eastport", "Westfield"],
"hours": [42, 31, 55, 24, 47, 38],
"score": [88, 74, 91, 65, 82, 79],
})
print(learners.sort_values(["track", "score"])[["track", "name", "score"]])
print(
learners.sort_values(["track", "score"], ascending=[True, False])
[["track", "name", "score"]]
)Output:
track name score
1 NumPy Jordan 74
4 NumPy Morgan 82
0 Python Avery 88
2 Python Casey 91
3 pandas Riley 65
5 pandas Quinn 79
track name score
4 NumPy Morgan 82
1 NumPy Jordan 74
2 Python Casey 91
0 Python Avery 88
5 pandas Quinn 79
3 pandas Riley 65Sort by label
sort_index() orders the rows by their labels, and axis=1 orders the columns by name instead, which is handy when two tables should line up for comparison.
import pandas as pd
learners = pd.DataFrame({
"name": ["Avery", "Jordan", "Casey", "Riley", "Morgan", "Quinn"],
"track": ["Python", "NumPy", "Python", "pandas", "NumPy", "pandas"],
"city": ["Northgate", "Eastport", "Northgate", "Westfield", "Eastport", "Westfield"],
"hours": [42, 31, 55, 24, 47, 38],
"score": [88, 74, 91, 65, 82, 79],
})
tagged = learners.set_index("name")
print(tagged.sort_index()[["track", "score"]])
print(tagged.sort_index(axis=1).head(2))Output:
track score
name
Avery Python 88
Casey Python 91
Jordan NumPy 74
Morgan NumPy 82
Quinn pandas 79
Riley pandas 65
city hours score track
name
Avery Northgate 42 88 Python
Jordan Eastport 31 74 NumPyJust the top few
nlargest and nsmallest sort and cut in one step, which is both shorter and quicker than sorting a big table to look at five rows. Missing values sort to the end by default.
import pandas as pd
learners = pd.DataFrame({
"name": ["Avery", "Jordan", "Casey", "Riley", "Morgan", "Quinn"],
"track": ["Python", "NumPy", "Python", "pandas", "NumPy", "pandas"],
"city": ["Northgate", "Eastport", "Northgate", "Westfield", "Eastport", "Westfield"],
"hours": [42, 31, 55, 24, 47, 38],
"score": [88, 74, 91, 65, 82, 79],
})
print(learners.nlargest(3, "score")[["name", "score"]])
print(learners.nsmallest(2, "hours")[["name", "hours"]])
print(learners["score"].rank(ascending=False).astype(int).tolist())Output:
name score
2 Casey 91
0 Avery 88
4 Morgan 82
name hours
3 Riley 24
1 Jordan 31
[2, 5, 1, 6, 3, 4]rank numbers the values without moving any rows.
Key takeaways
-
sort_values orders by cell values and sort_index by labels
-
A list of columns sorts by the first and breaks ties with the next
-
ascending can be a list, one value per sort column
-
nlargest and nsmallest beat sorting a whole table for a top-few view
-
Next: Column Types and astype
-
Previous: Removing Columns and Rows
Loading playground…
Check your understanding
Sorting Data Quiz
What does sort_values order by?
1 / 10