Pandas 数据排序

数据排序是数据整理的基本操作。Pandas 提供了灵活的排序功能,既可以按列的值排序,也可以按行索引或列名排序。通过 sort_values()sort_index(),你可以轻松将数据排列成所需的顺序。

📌 准备示例数据

import pandas as pd
import numpy as np

df = pd.DataFrame({
    '姓名': ['张三', '李四', '王五', '赵六', '陈七', '刘八'],
    '年龄': [28, 35, 42, 29, 31, np.nan],
    '工资': [8000, 12000, 15000, 9500, 11000, 10500],
    '部门': ['技术', '销售', '技术', '管理', '销售', '技术'],
    '入职年份': [2020, 2018, 2015, 2021, 2019, 2022]
}, index=['E', 'B', 'A', 'D', 'C', 'F'])

print("原始数据:")
print(df)

🔢 按值排序:sort_values()

这是最常用的排序方法,用于根据一列或多列的数值进行排序。

单列排序
# 按年龄升序(默认)
df.sort_values('年龄')

# 按工资降序
df.sort_values('工资', ascending=False)
多列排序
# 先按部门升序,再按工资降序
df.sort_values(['部门', '工资'], ascending=[True, False])

⚙️ 重要参数

by 排序列名
ascending 升序/降序
na_position 缺失值位置
inplace 原地修改
key 自定义排序键
# 处理缺失值:将 NaN 放在最前面
df.sort_values('年龄', na_position='first')

# 原地修改(不返回新对象)
df.sort_values('工资', ascending=False, inplace=True)

# 使用 key 参数:按年龄的绝对值排序(示例)
df_abs = pd.DataFrame({'值': [-5, 3, -2, 1]})
df_abs.sort_values('值', key=lambda col: abs(col))

🔖 按索引排序:sort_index()

对行索引或列索引进行排序,常用于数据对齐后恢复顺序。

# 按行索引升序(默认)
df.sort_index()

# 按行索引降序
df.sort_index(ascending=False)

# 按列名排序(axis=1)
df.sort_index(axis=1)

# 对 Series 也适用
s = pd.Series([1, 2, 3], index=['c', 'a', 'b'])
s.sort_index()

📊 综合示例

# 重新创建原始顺序的副本(索引乱序)
df_original = pd.DataFrame({
    '姓名': ['张三', '李四', '王五', '赵六', '陈七', '刘八'],
    '年龄': [28, 35, 42, 29, 31, np.nan],
    '工资': [8000, 12000, 15000, 9500, 11000, 10500],
    '部门': ['技术', '销售', '技术', '管理', '销售', '技术'],
    '入职年份': [2020, 2018, 2015, 2021, 2019, 2022]
}, index=['E', 'B', 'A', 'D', 'C', 'F'])

print("1. 按工资降序,缺失年龄的行在前:")
print(df_original.sort_values('工资', ascending=False, na_position='first'))

print("\n2. 先按部门升序,再按年龄降序:")
print(df_original.sort_values(['部门', '年龄'], ascending=[True, False]))

print("\n3. 按行索引排序(字母顺序):")
print(df_original.sort_index())

print("\n4. 按列名排序:")
print(df_original.sort_index(axis=1))

print("\n5. 自定义排序规则:按姓名长度排序")
df_original['姓名长度'] = df_original['姓名'].str.len()
df_original.sort_values('姓名长度', ascending=False, inplace=True)
print(df_original.drop('姓名长度', axis=1))

🧩 多级索引排序

对于具有 MultiIndex 的 DataFrame,sort_index() 可以按层级排序。

# 创建多级索引示例
arrays = [['A', 'A', 'B', 'B'], [1, 2, 1, 2]]
index = pd.MultiIndex.from_arrays(arrays, names=['字母', '数字'])
df_multi = pd.DataFrame({'值': [10, 5, 20, 15]}, index=index)

print("原始多级索引:")
print(df_multi)

print("\n按第一级索引升序,第二级降序:")
print(df_multi.sort_index(level=[0,1], ascending=[True, False]))

⚠️ 注意事项

inplace=True 谨慎使用:原地修改会改变原对象,且很多链式操作不支持 inplace。推荐使用默认方式(返回新对象)赋值,如 df = df.sort_values(...)
多列排序的 ascending 列表长度需与列数一致。例如 ascending=[True, False] 对应第一列升序、第二列降序。
排序稳定性:Pandas 排序目前是稳定的(即相等元素保持原有顺序),但不应依赖此特性,如有需要可自行指定 tie-breaking 列。
缺失值处理:na_position 只对排序列有效;若需控制其他列的缺失值,需单独处理。
最佳实践:
  • 排序前先通过 df.info() 确认数据类型,避免因类型错误导致排序异常(如字符串数字混排)。
  • 如果需要保留原始行顺序,可以先记录原始索引,排序后恢复。
  • 对于大数据集,考虑性能:多列排序可能较慢,可尝试先对一列排序再分组。