按列值排序
使用 sort_values() 按一个或多个列对 DataFrame 排序,控制升序或降序,并处理 NaN 的位置。
按列值排序 是 CoddyKit 上的免费 Pandas & NumPy Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Pandas & NumPy Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Pandas & NumPy Academy 课程共包含 4 节课。
排序为何重要
对 DataFrame 进行排序对于展示(前 N 名报告、排行榜)、正确性(时间序列操作要求按时间顺序排列)和性能(已排序索引上的二分查找为 O(log n),而不是 O(n))都很重要。Pandas 的 sort_values() 方法是按列内容排序的主要工具,它会返回一个新的 DataFrame,而不会修改原始对象。
import pandas as pd
df = pd.DataFrame({
'name': ['Dave', 'Alice', 'Carol', 'Bob'],
'score': [75, 92, 88, 65]
})
# Sort by score descending (highest first)
ranked = df.sort_values('score', ascending=False)
print(ranked)
# name score
# 1 Alice 92
# 2 Carol 88
# 0 Dave 75
# 3 Bob 65sort_values() — 基本用法
DataFrame.sort_values(by) 会按照指定列中的值对行进行排序。by 参数可以接受单个列名(字符串),也可以接受列名列表,以执行多关键字排序。默认情况下,排序为升序(从最小值开始)。传入 ascending=False 可改为降序。
import pandas as pd
df = pd.DataFrame({
'product': ['B', 'A', 'C', 'A', 'B'],
'price': [20, 10, 30, 15, 25]
})
# Ascending by price (default)
print(df.sort_values('price'))
# product price
# 1 A 10
# 3 A 15
# 0 B 20
# 4 B 25
# 2 C 30按多个列排序
将列名的列表传递给 sort_values(by=) 后,系统会先按第一列排序,然后使用第二列处理并列值,依此类推。ascending 参数也可以是一个与列顺序对应的布尔值列表,从而允许为每个关键字设置不同的排序方向。
import pandas as pd
df = pd.DataFrame({
'dept': ['HR', 'Eng', 'HR', 'Eng', 'Sales'],
'salary': [50000, 90000, 60000, 80000, 70000],
'name': ['Alice', 'Bob', 'Carol', 'Dave', 'Eve']
})
# Sort by dept A-Z, then by salary descending within each dept
sorted_df = df.sort_values(
by=['dept', 'salary'],
ascending=[True, False]
)
print(sorted_df)
# dept salary name
# 1 Eng 90000 Bob
# 3 Eng 80000 Dave
# 2 HR 60000 Carol
# 0 HR 50000 Alice
# 4 Sales 70000 Eve使用 na_position 放置 NaN
默认情况下,无论升序还是降序,NaN 值都会被排到结果的末尾。使用 na_position 参数可以控制这一点:'last'(默认值)或 'first'。在排名表中,决定 NaN 的位置很重要——缺失值可能表示“未知”,应与有效的排名条目明确分开。
import pandas as pd
import numpy as np
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Carol', 'Dave'],
'score': [92, np.nan, 88, np.nan]
})
# NaN last (default)
print(df.sort_values('score', ascending=False, na_position='last'))
# name score
# 0 Alice 92.0
# 2 Carol 88.0
# 1 Bob NaN
# 3 Dave NaN
# NaN first
print(df.sort_values('score', na_position='first').head(2))稳定排序与 kind= 参数
Pandas 默认使用稳定排序(归并排序,复杂度为 O(n log n)):当两行在排序关键字上的值相等时,会保留它们的原始相对顺序。当您先按主关键字排序,再按次关键字排序时,这种稳定性非常重要:在次关键字相同的行中,主排序顺序仍会得到保留。您可以使用 kind='quicksort'(速度更快但不稳定)或 kind='heapsort' 更改算法。
import pandas as pd
df = pd.DataFrame({
'group': ['A', 'B', 'A', 'B'],
'value': [10, 10, 20, 20],
'original_row': [0, 1, 2, 3]
})
# Stable sort: equal values keep original relative order
result = df.sort_values('value', kind='mergesort')
print(result)
# group value original_row
# 0 A 10 0
# 1 B 10 1 <- row 0 before row 1 (stable)
# 2 A 20 2
# 3 B 20 3inplace=True 与重新赋值
与大多数 Pandas 方法一样,sort_values() 默认会返回一个新的 DataFrame。传入 inplace=True 会直接修改原 DataFrame,并返回 None。在现代 Pandas 中通常不建议使用 inplace,因为这会使代码更难构建流程和调试——始终重新赋值更简单:df = df.sort_values('col')。
import pandas as pd
df = pd.DataFrame({'x': [3, 1, 4, 1, 5]})
# Preferred: reassign
df = df.sort_values('x')
print(df['x'].tolist()) # [1, 1, 3, 4, 5]
# Alternative: inplace (not recommended for pipelines)
df2 = pd.DataFrame({'x': [3, 1, 4]})
df2.sort_values('x', inplace=True)
print(df2['x'].tolist()) # [1, 3, 4]排序后重置索引
排序后,行索引仍反映原始位置。在按降序排列的表中,行 0 现在可能具有索引 4。调用 .reset_index(drop=True) 可重新分配从 0 开始的连续索引。在使用 .iloc[0] 可靠地获取排名第一的行之前,或将数据导出到文件之前,这一步非常重要,否则索引间隔可能令人困惑。
import pandas as pd
df = pd.DataFrame({'score': [70, 90, 80]})
sorted_df = df.sort_values('score', ascending=False)
print(sorted_df)
# score
# 1 90
# 2 80
# 0 70
# Clean sequential index
reset_df = sorted_df.reset_index(drop=True)
print(reset_df)
# score
# 0 90
# 1 80
# 2 70使用 nlargest() 和 nsmallest() 获取前 N 项
如果要根据某列的值选择前 N 行或后 N 行,df.nlargest(n, 'col') 和 df.nsmallest(n, 'col') 比对整个 DataFrame 排序后再切片更高效。它们使用部分排序(堆选择),复杂度为 O(n log k),而不是 O(n log n),这对大型 DataFrames 很重要。
import pandas as pd
df = pd.DataFrame({
'product': ['A', 'B', 'C', 'D', 'E'],
'revenue': [5000, 12000, 8000, 3000, 15000]
})
# Top 3 by revenue
top3 = df.nlargest(3, 'revenue')
print(top3)
# product revenue
# 4 E 15000
# 1 B 12000
# 2 C 8000
# Bottom 2 by revenue
bottom2 = df.nsmallest(2, 'revenue')
print(bottom2)按类别顺序对分类列排序
对包含有序 Categorical 数据类型的列进行排序时,sort_values() 会遵循类别顺序,而不是字母顺序。这对于正确排列优先级、严重程度或尺寸标签至关重要——'Small' 应排在 'Medium' 前,'Medium' 应排在 'Large' 前,而不是按字母顺序将 'Large' 排在最前面。
import pandas as pd
df = pd.DataFrame({
'size': pd.Categorical(
['Large', 'Small', 'Medium', 'Small', 'Large'],
categories=['Small', 'Medium', 'Large'],
ordered=True
),
'count': [10, 5, 8, 3, 7]
})
print(df.sort_values('size'))
# size count
# 1 Small 5
# 3 Small 3
# 2 Medium 8
# 0 Large 10
# 4 Large 7将排序与其他操作链接
由于 sort_values() 会返回一个 DataFrame,因此它可以自然地融入方法链。一种典型模式是:筛选行 → 聚合 → 排序 → 展示前 N 项。链式操作可以让转换流程保持线性且易于阅读。
import pandas as pd
df = pd.DataFrame({
'dept': ['Eng', 'HR', 'Eng', 'Sales', 'HR', 'Eng'],
'salary': [90000, 50000, 120000, 70000, 55000, 80000]
})
result = (
df
.groupby('dept')['salary'].mean()
.reset_index()
.sort_values('salary', ascending=False)
.head(2)
)
print(result)
# dept salary
# 0 Eng 96666.67
# 2 Sales 70000.00实践:前 5 名产品报告
下面是一个端到端的实际示例,用于生成按收入排列的前 5 名产品报告:加载数据,计算每种产品的总收入,按降序排序,取前 5 项,重置索引以生成整洁的排名编号,并添加一个用于展示的排名列。
import pandas as pd
orders = pd.DataFrame({
'product': ['A', 'B', 'A', 'C', 'B', 'D', 'E', 'A', 'C', 'E'],
'revenue': [100, 200, 150, 80, 300, 60, 400, 120, 90, 350]
})
top5 = (
orders
.groupby('product')['revenue'].sum()
.reset_index()
.sort_values('revenue', ascending=False)
.head(5)
.reset_index(drop=True)
)
top5.index = top5.index + 1 # rank from 1
top5.index.name = 'rank'
print(top5)快速检查
测试您对按列值排序 DataFrames 的理解。
课程回顾
本课中,您学习了:sort_values(by=) 可以按一个或多个列排序,ascending= 可以是列表,以便为每个关键字设置不同方向,na_position='last' 可以控制 NaN 的位置,而 nlargest()/nsmallest() 可以高效提取前 N 行或后 N 行,无需对整个 DataFrame 排序。排序后应始终使用 reset_index(),以生成整洁的连续输出。接下来,我们将按 DataFrame 索引排序。
常见问题解答
「按列值排序」课时是免费的吗?
是的 — 「按列值排序」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Pandas & NumPy Academy 课程的其余内容,请升级到 CoddyKit PRO。 Pandas & NumPy Academy 课程共包含 4 节课。
「按列值排序」这节课中我会学到什么?
使用 sort_values() 按一个或多个列对 DataFrame 排序,控制升序或降序,并处理 NaN 的位置。 你通过在浏览器中直接运行的动手代码来练习 Pandas & NumPy Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Pandas & NumPy Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Pandas & NumPy Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「按列值排序」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Pandas & NumPy Academy 课中编写并运行代码吗?
能。每节 Pandas & NumPy Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。