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']])
排名方法 相同值处理 示例(分数92,92,85)
average(默认) 取平均排名 1.5, 1.5, 3
min 取最小排名 1, 1, 3
max 取最大排名 2, 2, 3
dense 相同排名,下一个连续 1, 1, 2
first 按出现顺序排名 1, 2, 3

六、实际应用场景

场景一:找出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参数的效果。

标签: pandas 排序 sort_values DataFrame Python 排名

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: pandas DataFrame增删改操作教程 - 数据添加删除修改详解 下一篇: pandas groupby分组聚合教程 - 数据分析核心技巧

poll相关推荐