NumPy 中文教程

第一部分:基础认知与环境准备
第 1 章 全面认识 NumPy
第 2 章 开发环境搭建与验证
第二部分:核心对象 ——ndarray 数组
第 3 章 ndarray 数组基础
第 4 章 数组的形状与维度操作
第四部分:高级应用与数据处理
第 8 章 数组的排序、查找与去重
第 9 章 缺失值与异常值处理
第 10 章 随机数生成与抽样
第 11 章 文件读写与数据交互
第五部分:实战场景与落地应用
第 12 章 数值计算实战
第 13 章 数据分析实战
第六部分:优化进阶与问题解决
第 14 章 NumPy 性能优化
第 15 章 NumPy 进阶扩展
第 16 章 常见问题与解决方案

8.1 数组排序

NumPy数组排序全面指南:快速排序、轴排序、间接排序与性能优化

NumPy 中文教程

本NumPy教程详细讲解数组排序方法,包括快速排序(np.sort和ndarray.sort)、按轴排序、稳定排序、降序排序、间接排序(如argsort、lexsort、partition)以及排序算法选择与性能优化,适合数据科学初学者和开发者轻松入门并掌握高效数据处理技巧。

推荐工具
PyCharm专业版开发必备

功能强大的Python IDE,提供智能代码补全、代码分析、调试和测试工具,提高Python开发效率。特别适合处理列表等数据结构的开发工作。

了解更多

NumPy数组排序详细教程

引言

在数据科学和机器学习中,数组排序是一个基础且重要的操作。NumPy作为Python中强大的数值计算库,提供了多种高效的排序方法,帮助用户快速处理和分析数据。本教程将从基础到高级,逐步介绍NumPy中的数组排序功能,确保新人能轻松理解。


快速排序:np.sort() 和 ndarray.sort()

NumPy提供了两种快速排序函数:np.sort()ndarray.sort()。它们的核心区别在于是否修改原始数组。

  • np.sort(): 返回一个新数组,原始数组保持不变。这适用于需要保留原始数据的情况。
  • ndarray.sort(): 原地排序,直接在原始数组上修改,节省内存但改变原数据。

示例代码:

import numpy as np

# 创建一个示例数组
arr = np.array([3, 1, 4, 1, 5])

# 使用 np.sort(),返回新数组
sorted_arr = np.sort(arr)
print("np.sort() 结果:", sorted_arr)  # 输出:[1 1 3 4 5]
print("原始数组:", arr)              # 输出:[3 1 4 1 5],保持不变

# 使用 ndarray.sort(),原地排序
arr.sort()
print("ndarray.sort() 后:", arr)     # 输出:[1 1 3 4 5],原数组被修改

默认情况下,NumPy使用快速排序算法('quicksort'),速度快但不稳定。可通过kind参数选择其他算法,如'mergesort'或'heapsort'。


按轴排序

在多维数组中,可以指定轴(axis)进行排序。例如,对二维数组按行或列排序。

  • axis=0: 按列排序,每列独立排序。
  • axis=1: 按行排序,每行独立排序。
  • 如果不指定轴,默认对整个数组展平后排序。

示例代码:

# 创建一个二维数组
arr_2d = np.array([[3, 2], [1, 4]])

# 按轴排序
sorted_axis0 = np.sort(arr_2d, axis=0)  # 按列排序
print("按列排序:", sorted_axis0)        # 输出:[[1 2], [3 4]]

sorted_axis1 = np.sort(arr_2d, axis=1)  # 按行排序
print("按行排序:", sorted_axis1)        # 输出:[[2 3], [1 4]]

这在大数据处理中非常有用,例如对数据表的列进行排序。


稳定排序

稳定排序指排序后相等元素的相对顺序保持不变。在NumPy中,可以通过设置kind='stable'或使用'mergesort'来实现稳定排序。

  • 稳定性: 如果数据中有重复值,稳定排序确保这些重复值的原始顺序在排序后不变。
  • 应用场景:如处理带有多重键的数据,需要保持次级顺序。

示例代码:

# 创建一个带重复值的数组
arr_stable = np.array([('b', 2), ('a', 1), ('b', 1)], dtype=[('letter', 'U1'), ('number', 'i4')])

# 使用稳定排序(按字母排序,保持数字顺序)
sorted_stable = np.sort(arr_stable, order='letter', kind='stable')
print("稳定排序结果:", sorted_stable)
# 输出:[(‘a’, 1), (‘b’, 2), (‘b’, 1)],注意 'b' 的原始顺序保持

默认'quicksort'不稳定,所以对于需要稳定性的场景,推荐使用'mergesort'或'stable'。


降序排序

NumPy默认排序是升序(从小到大)。要实现降序(从大到小),有以下方法:

  1. 使用切片[::-1]: 对排序后的数组进行反转。
  2. 设置参数: 在np.sort()ndarray.sort()中,可以通过order参数或结合kind实现降序,但更常见的是反转。

示例代码:

arr_desc = np.array([5, 2, 8, 1])

# 方法1:先升序排序,再反转
sorted_asc = np.sort(arr_desc)  # 升序排序
sorted_desc = sorted_asc[::-1]   # 反转得到降序
print("降序排序(反转):", sorted_desc)  # 输出:[8 5 2 1]

# 方法2:使用参数(适用于结构化数组,但通常推荐反转)
# 例如,对于数字数组,直接反转更简单

对于简单数组,反转是最直接的方法。


间接排序

间接排序不直接对数组排序,而是返回排序后的索引或其他信息,常用于数据索引或部分排序。

argsort()

返回排序后元素在原数组中的索引位置。

arr_indirect = np.array([3, 1, 2])
indices = np.argsort(arr_indirect)
print("argsort() 索引:", indices)  # 输出:[1 2 0]
print("排序后数组:", arr_indirect[indices])  # 输出:[1 2 3]

lexsort()

按多个键排序,返回索引。常用于多列数据排序。

keys = (np.array([2, 1, 1]), np.array([3, 1, 2]))  # 第一个键优先级高
lex_indices = np.lexsort(keys)
print("lexsort() 索引:", lex_indices)  # 输出:[1 2 0],先按第二个键排序

partition()

部分排序,将数组分成两部分:前k个最小(或最大)元素在左边,其余在右边,但不完全排序。

arr_part = np.array([3, 4, 2, 1])
partitioned = np.partition(arr_part, 2)  # 前2个最小元素在左边
print("partition() 结果:", partitioned)  # 输出可能是 [2 1 3 4],左边是前2小

排序算法选择与性能

NumPy支持多种排序算法,通过kind参数指定:

  • 'quicksort'(默认): 快速排序,平均时间复杂度O(n log n),不稳定,适合大多数情况。
  • 'mergesort': 归并排序,稳定,时间复杂度O(n log n),但内存使用较高。
  • 'heapsort': 堆排序,不稳定,时间复杂度O(n log n),内存效率好。
  • 'stable': 稳定排序的别名,通常指向'mergesort'。

性能比较:

  • 小数组:所有算法差异不大。
  • 大数组:'quicksort'通常最快,但如果数据有重复或需要稳定排序,选择'mergesort'。
  • 内存限制:'heapsort'内存使用较低。

如何选择:

  • 默认使用'quicksort'以获得最佳速度。
  • 如果需要稳定排序,使用'mergesort'或'stable'。
  • 测试性能:对于特定数据集,可以测试不同算法以找到最优。

示例:

import time

arr_large = np.random.rand(10000)

# 测试不同算法的性能
for kind in ['quicksort', 'mergesort', 'heapsort']:
    start = time.time()
    np.sort(arr_large, kind=kind)
    end = time.time()
    print(f"{kind} 耗时: {end - start:.6f} 秒")

总结与最佳实践

  1. 基础排序: 使用np.sort()ndarray.sort(),注意原地与非原地区别。
  2. 轴排序: 利用axis参数处理多维数据。
  3. 稳定排序: 当数据有重复值时,选择'mergesort'或'stable'。
  4. 降序排序: 通过反转排序结果实现。
  5. 间接排序: 使用argsort、lexsort或partition进行灵活索引和部分排序。
  6. 算法选择: 根据数据大小、稳定性需求和内存限制选择合适的算法,通常'quicksort'是默认好选择。

通过本教程,您应该能熟练使用NumPy进行数组排序,并在实际项目中优化性能。多加练习,结合具体数据场景,将能更高效地处理数据任务。

开发工具推荐
Python开发者工具包

包含虚拟环境管理、代码格式化、依赖管理、测试框架等Python开发全流程工具,提高开发效率。特别适合处理复杂数据结构和算法。

获取工具包