Skip to content

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'])

如何按多列以不同顺序排序?

将布尔值列表传给ascendingdf.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=Truedf.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)

📚