Pandas Sort Values:Python中DataFrame排序完全指南
Updated on
未排序的数据难以分析。你在成千上万行数据中寻找最高销售额、最近日期或最低错误率——却错过了排序后显而易见的模式。Python列表排序可以处理简单场景,但DataFrame有多列、混合类型和缺失值,列表无法处理这些情况。
Pandas的sort_values()可以按一列或多列对任何DataFrame进行排序,并完全控制升序/降序、空值位置和稳定性。本指南涵盖了实际数据工作中会遇到的所有排序模式。
使用sort_values()进行基本排序
按单列排序
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
'score': [85, 92, 78, 95, 88],
'age': [25, 30, 22, 28, 35]
})
# 按score排序(默认升序)
sorted_df = df.sort_values('score')
print(sorted_df)
# name score age
# 2 Charlie 78 22
# 0 Alice 85 25
# 4 Eve 88 35
# 1 Bob 92 30
# 3 Diana 95 28降序排序
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
'score': [85, 92, 78, 95, 88],
'age': [25, 30, 22, 28, 35]
})
# 最高分优先
sorted_df = df.sort_values('score', ascending=False)
print(sorted_df)
# name score age
# 3 Diana 95 28
# 1 Bob 92 30
# 4 Eve 88 35
# 0 Alice 85 25
# 2 Charlie 78 22就地排序
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'score': [85, 92, 78]
})
# 直接修改df(不创建副本)
df.sort_values('score', inplace=True)
print(df)
# name score
# 2 Charlie 78
# 0 Alice 85
# 1 Bob 92多列排序
按多列排序
import pandas as pd
df = pd.DataFrame({
'department': ['Sales', 'Engineering', 'Sales', 'Engineering', 'Sales'],
'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
'salary': [70000, 85000, 65000, 90000, 70000]
})
# 先按部门排序,然后按各部门内的薪资排序
sorted_df = df.sort_values(['department', 'salary'])
print(sorted_df)
# department name salary
# 1 Engineering Bob 85000
# 3 Engineering Diana 90000
# 2 Sales Charlie 65000
# 0 Sales Alice 70000
# 4 Sales Eve 70000混合升序/降序
import pandas as pd
df = pd.DataFrame({
'department': ['Sales', 'Engineering', 'Sales', 'Engineering', 'Sales'],
'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
'salary': [70000, 85000, 65000, 90000, 70000]
})
# 部门升序,薪资降序
sorted_df = df.sort_values(
['department', 'salary'],
ascending=[True, False]
)
print(sorted_df)
# department name salary
# 3 Engineering Diana 90000
# 1 Engineering Bob 85000
# 0 Sales Alice 70000
# 4 Sales Eve 70000
# 2 Sales Charlie 65000处理缺失值(NaN)
默认情况下,无论排序方向如何,NaN值都会放在末尾。使用na_position来控制:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'score': [85, np.nan, 78, np.nan]
})
# NaN在末尾(默认)
print(df.sort_values('score'))
# name score
# 2 Charlie 78.0
# 0 Alice 85.0
# 1 Bob NaN
# 3 Diana NaN
# NaN在开头
print(df.sort_values('score', na_position='first'))
# name score
# 1 Bob NaN
# 3 Diana NaN
# 2 Charlie 78.0
# 0 Alice 85.0使用sort_index()按索引排序
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'score': [85, 92, 78]
}, index=[2, 0, 1])
# 按索引排序
print(df.sort_index())
# name score
# 0 Bob 92
# 1 Charlie 78
# 2 Alice 85
# 按列名排序(axis=1)
df2 = pd.DataFrame({
'c': [1, 2], 'a': [3, 4], 'b': [5, 6]
})
print(df2.sort_index(axis=1))
# a b c
# 0 3 5 1
# 1 4 6 2排序后重置索引
排序后,原始索引会被保留。要获得干净的顺序索引:
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'score': [85, 92, 78]
})
sorted_df = df.sort_values('score').reset_index(drop=True)
print(sorted_df)
# name score
# 0 Charlie 78
# 1 Alice 85
# 2 Bob 92使用drop=True丢弃旧索引。不使用该参数时,旧索引会变成一列。
自定义排序顺序
使用分类类型
import pandas as pd
df = pd.DataFrame({
'priority': ['Medium', 'High', 'Low', 'High', 'Medium'],
'task': ['Task A', 'Task B', 'Task C', 'Task D', 'Task E']
})
# 定义自定义顺序
priority_order = pd.CategoricalDtype(['Low', 'Medium', 'High'], ordered=True)
df['priority'] = df['priority'].astype(priority_order)
sorted_df = df.sort_values('priority')
print(sorted_df)
# priority task
# 2 Low Task C
# 0 Medium Task A
# 4 Medium Task E
# 1 High Task B
# 3 High Task D使用key参数
import pandas as pd
df = pd.DataFrame({
'name': ['alice', 'Bob', 'CHARLIE', 'diana'],
'score': [85, 92, 78, 95]
})
# 不区分大小写排序
sorted_df = df.sort_values('name', key=lambda x: x.str.lower())
print(sorted_df)
# name score
# 0 alice 85
# 1 Bob 92
# 2 CHARLIE 78
# 3 diana 95方法比较
| 方法 | 用途 | 修改原始数据? | 返回值 |
|---|---|---|---|
sort_values(col) | 按列值排序 | 否(除非inplace=True) | 排序后的DataFrame |
sort_values([col1, col2]) | 按多列排序 | 否(除非inplace=True) | 排序后的DataFrame |
sort_index() | 按行索引排序 | 否(除非inplace=True) | 排序后的DataFrame |
nsmallest(n, col) | 获取n个最小值 | 否 | DataFrame子集 |
nlargest(n, col) | 获取n个最大值 | 否 | DataFrame子集 |
rank() | 为值分配排名 | 否 | 排名Series |
性能技巧
使用nlargest()和nsmallest()获取Top-N
当你只需要前N行或后N行时,nlargest()和nsmallest()比对整个DataFrame排序更快:
import pandas as pd
import numpy as np
# 大型DataFrame
df = pd.DataFrame({
'id': range(1_000_000),
'value': np.random.randn(1_000_000)
})
# 更快:只查找前10
top_10 = df.nlargest(10, 'value')
# 更慢:排序所有数据,然后切片
top_10_slow = df.sort_values('value', ascending=False).head(10)稳定排序与不稳定排序
import pandas as pd
df = pd.DataFrame({
'group': ['A', 'B', 'A', 'B'],
'value': [1, 1, 2, 2],
'order': [1, 2, 3, 4]
})
# 稳定排序(默认)保留相同值的原始顺序
stable = df.sort_values('value', kind='mergesort') # 默认
# 不稳定排序(对大数据集更快)
unstable = df.sort_values('value', kind='quicksort')实用示例
日期排序
import pandas as pd
df = pd.DataFrame({
'event': ['Launch', 'Meeting', 'Deadline', 'Review'],
'date': pd.to_datetime(['2026-03-15', '2026-01-10', '2026-02-28', '2026-01-05'])
})
# 按时间顺序排列
print(df.sort_values('date'))
# event date
# 3 Review 2026-01-05
# 1 Meeting 2026-01-10
# 2 Deadline 2026-02-28
# 0 Launch 2026-03-15结合GroupBy排序
import pandas as pd
df = pd.DataFrame({
'store': ['A', 'A', 'B', 'B', 'A', 'B'],
'product': ['X', 'Y', 'X', 'Y', 'Z', 'Z'],
'revenue': [100, 250, 150, 300, 200, 175]
})
# 每个商店中按收入排名最高的产品
top_per_store = (df.sort_values('revenue', ascending=False)
.groupby('store')
.head(1))
print(top_per_store)
# store product revenue
# 3 B Y 300
# 1 A Y 250可视化探索排序数据
在对DataFrame排序以发现模式之后,PyGWalker (opens in a new tab)让你可以在Jupyter中通过交互式拖拽图表探索相同的数据——无需额外代码:
import pygwalker as pyg
walker = pyg.walk(sorted_df)常见问题
如何在pandas中按列对DataFrame进行排序?
使用df.sort_values('column_name')进行升序排序,或df.sort_values('column_name', ascending=False)进行降序排序。对于多列,传入列表:df.sort_values(['col1', 'col2'])。
如何按多列以不同顺序排序?
将布尔值列表传给ascending:df.sort_values(['col1', 'col2'], ascending=[True, False])。这会将col1按升序排序,col2按降序排序。
排序时NaN值放在哪里?
默认情况下,无论排序方向如何,NaN值都放在末尾。使用na_position='first'将它们放在开头:df.sort_values('col', na_position='first')。
sort_values和sort_index有什么区别?
sort_values()按列值排序。sort_index()按行索引(或使用axis=1按列索引)排序。数据排序使用sort_values,需要按索引标签排序时使用sort_index。
如何就地排序DataFrame而不创建副本?
传入inplace=True:df.sort_values('col', inplace=True)。这会修改原始DataFrame并返回None。但现代pandas风格更推荐重新赋值:df = df.sort_values('col')。
总结
sort_values()是pandas中对DataFrame排序的主要工具。使用单列名进行简单排序,使用列表进行多列排序,使用ascending参数控制方向。使用na_position处理缺失值,使用nlargest()/nsmallest()进行Top-N查询,使用CategoricalDtype进行自定义排序。请记住排序默认返回新的DataFrame——如果需要干净的顺序索引,请使用reset_index(drop=True)。