pin_drop当前位置:知识文库 ❯ 图文
pandas DataFrame排序教程 - sort_values排序方法详解
数据排序是数据分析中最基础也最重要的操作之一。pandas提供了强大的排序功能,包括按值排序sort_values()和按索引排序sort_index()。本文将全面介绍DataFrame的排序方法。
一、sort_values基本用法
sort_values()是最常用的排序方法,可以按单列或多列的值进行排序。
代码示例
import pandas as pd
import numpy as np
# 创建示例数据
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'age': [25, 30, 35, 28, 22],
'salary': [8000, 12000, 15000, 9000, 7500],
'department': ['技术', '销售', '技术', '人事', '销售']
})
# 按单列升序排序(默认)
df_sorted = df.sort_values(by='age')
print("按年龄升序:")
print(df_sorted)
# 按单列降序排序
df_sorted = df.sort_values(by='salary', ascending=False)
print("按薪资降序:")
print(df_sorted)关键参数说明:
-
by:指定排序的列名,可以是字符串或列表
-
ascending:布尔值,True为升序(默认),False为降序
-
inplace:是否原地修改,默认False
-
kind:排序算法,可选'quicksort'、'mergesort'、'heapsort'、'stable'
-
na_position:缺失值位置,'first'或'last'
二、多列排序
多列排序非常实用,可以指定多个排序键,按优先级依次排序。
代码示例
# 按部门升序、薪资降序排序
df_sorted = df.sort_values(
by=['department', 'salary'],
ascending=[True, False]
)
print("按部门升序、薪资降序:")
print(df_sorted)
# 多列排序的实际意义
# 先按部门分组显示,每个部门内部按薪资从高到低排列
df_sorted = df.sort_values(
by=['department', 'age', 'salary'],
ascending=[True, True, False],
ignore_index=True # 重置索引
)
print("三级排序结果:")
print(df_sorted)提示:
ascending参数可以是单个布尔值(对所有列生效)或布尔列表(每列独立指定)。列表长度必须与by参数一致。
三、处理缺失值排序
当数据中存在NaN值时,可以通过na_position参数控制缺失值的位置。
代码示例
# 创建含缺失值的数据
df_na = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie', 'David'],
'score': [85, np.nan, 92, 78]
})
# 缺失值放最后(默认)
df_sorted = df_na.sort_values(by='score', na_position='last')
print("缺失值在最后:")
print(df_sorted)
# 缺失值放最前
df_sorted = df_na.sort_values(by='score', na_position='first')
print("缺失值在最前:")
print(df_sorted)四、sort_index索引排序
除了按值排序,还可以按索引排序,这在处理时间序列数据时非常有用。
代码示例
# 创建乱序索引的DataFrame
df = pd.DataFrame({
'value': [100, 200, 300, 400]
}, index=[3, 1, 4, 2])
# 按索引升序排序
df_sorted = df.sort_index()
print("按索引升序:")
print(df_sorted)
# 按索引降序排序
df_sorted = df.sort_index(ascending=False)
print("按索引降序:")
print(df_sorted)
# 时间序列索引排序
dates = pd.to_datetime(['2024-03-15', '2024-01-10', '2024-02-20'])
df_time = pd.DataFrame({
'sales': [5000, 6000, 5500]
}, index=dates)
# 按日期排序
df_time_sorted = df_time.sort_index()
print("按日期排序:")
print(df_time_sorted)五、rank排名函数
rank()函数可以为数据生成排名,而不是重新排列数据。
代码示例
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'score': [85, 92, 78, 92, 88]
})
# 默认排名(相同值取平均排名)
df['rank_avg'] = df['score'].rank(ascending=False)
# 最小排名(相同值取最小排名)
df['rank_min'] = df['score'].rank(method='min', ascending=False)
# 密集排名(相同值排名相同,下一个排名连续)
df['rank_dense'] = df['score'].rank(method='dense', ascending=False)
print(df[['name', 'score', 'rank_avg', 'rank_min', 'rank_dense']])六、实际应用场景
场景一:找出Top N记录
代码示例
# 找出薪资最高的3名员工
top3 = df.nlargest(3, 'salary')
print("薪资Top 3:")
print(top3)
# 找出年龄最小的2名员工
bottom2 = df.nsmallest(2, 'age')
print("年龄最小2人:")
print(bottom2)
# nlargest/nsmallest 比 sort_values().head() 更高效
# 尤其适用于大数据集场景二:自定义排序规则
代码示例
# 按部门自定义顺序排序
department_order = ['技术', '销售', '人事', '财务']
df['dept_order'] = df['department'].map(
{dept: idx for idx, dept in enumerate(department_order)}
)
df_sorted = df.sort_values('dept_order').drop(columns=['dept_order'])
print("按自定义部门顺序:")
print(df_sorted)
# 使用 CategoricalDtype 更优雅
from pandas.api.types import CategoricalDtype
cat_type = CategoricalDtype(categories=department_order, ordered=True)
df['department_cat'] = df['department'].astype(cat_type)
df_sorted = df.sort_values('department_cat')
print(df_sorted)场景三:分组内排序
代码示例
# 每个部门内按薪资排序
df['rank_in_dept'] = df.groupby('department')['salary'].rank(
method='dense', ascending=False
)
df_sorted = df.sort_values(['department', 'rank_in_dept'])
print("各部门内薪资排名:")
print(df_sorted[['name', 'department', 'salary', 'rank_in_dept']])小贴士
性能提示:当只需要获取Top N记录时,使用nlargest()或nsmallest()比先排序再取head更高效。另外,如果需要稳定排序(相同值保持原始顺序),设置kind='stable'。更多排序技巧可参考官方文档。
常见问题
sort_values 和 sort_index 有什么区别?
sort_values 按列的值进行排序,是最常用的排序方式;sort_index 按行索引或列名排序,常用于时间序列数据或需要按索引顺序整理数据的场景。
如何按中文拼音排序?
pandas默认按Unicode码点排序,中文不是按拼音排序。需要借助第三方库如pypinyin:df['pinyin'] = df['name'].apply(lambda x: pinyin.get(x, format='strip')); df = df.sort_values('pinyin')。
nlargest/nsmallest 和 sort_values().head() 哪个更快?
nlargest/nsmallest 使用堆算法,时间复杂度为 O(n log k),而 sort_values 需要完全排序,时间复杂度为 O(n log n)。当 n 很大且 k 很小时,nlargest/nsmallest 显著更快。
排序后索引乱了怎么办?
排序后原索引会保留,如果需要连续的数字索引,可以使用 ignore_index=True 参数:df.sort_values(by='age', ignore_index=True),或者排序后调用 reset_index(drop=True)。
练习1
创建一个包含学生姓名、语文成绩、数学成绩、英语成绩的DataFrame,按总分降序排列,并为每个学生生成班级排名。
练习2
有一份订单数据,包含订单日期、金额、地区。请实现:先按地区排序,同地区内按日期升序,同地区同日期按金额降序。
练习3
使用rank函数为员工数据生成多种排名:薪资排名、年龄排名,以及部门内的薪资排名。比较不同method参数的效果。
本文涉及AI创作
内容由AI创作,请仔细甄别