NumPy 函数手册:排序与搜索
在数据分析、科学计算以及机器学习中经常需要对数组进行排序与查找。例如• 对数据进行排序以分析分布• 获取排序后的索引以重排数据• 查找元素在有序数组中的位置• 去除重复元素并统计频率按照功能划分NumPy 中常见的数组排序与搜索函数通常可以分为以下几类1排序操作2索引排序3部分排序4搜索定位5去重与统计一、排序操作sort()返回排序后的新数组。numpy.sort(a, axis-1, kindNone, orderNone)ndarray.sort(axis-1, kindNone, orderNone)参数说明• a输入数组• axis排序轴默认最后一个轴• kind排序算法quicksort快速排序默认速度快不稳定heapsort堆排序不稳定mergesort稳定排序接口之一常用于兼容旧写法stable稳定排序接口推荐• order结构化数组字段排序field按单个字段排序 [field1, field2]按多个字段排序从左到右优先级递减返回值numpy.sort() 返回新数组ndarray.sort() 原地修改。示例 1二维数组沿列轴排序import numpy as np a np.array([[3, 1, 2], [6, 4, 5]]) b np.sort(a) # 默认 axis-1输出[[1 2 3] [4 5 6]]说明sort() 的比较是沿指定 axis 对该轴上的元素进行标量排序其余轴仅用于确定分组。对于二维数组当 axis-1 时每一行独立按列方向进行排序。示例 2二维数组沿行轴排序axis0a np.array([[6, 1, 5], [3, 4, 2]]) b np.sort(a, axis0)输出[[3 1 2] [6 4 5]]说明每一列独立排序。示例 3结构化数组字段排序import numpy as np a np.array([ (Alice, 25), (Bob, 20), (Charlie, 25)], dtype[(name, U10), (age, i4)]) # 按 age 排序np.sort(a, orderage) # 按 age再按 name 排序np.sort(a, order[age, name])示例 4原地排序a.sort(axis1)说明ndarray.sort() 会直接修改原数组。特别说明sort() 仅直接提供升序排序。如需降序可对排序结果在相应轴上反转一维数组中常见写法是 [::-1]。二、索引排序argsort()返回排序后元素在原数组的索引顺序。numpy.argsort(a, axis-1, kindNone, orderNone)参数说明• a输入数组• axis排序轴• kind排序算法同 sort• order结构化数组字段排序同 sort示例 1二维数组沿列轴排序索引a np.array([[3, 1, 2], [6, 4, 5]]) idx np.argsort(a, axis1)print(idx)输出[[1 2 0] [1 2 0]]说明argsort() 给出的不是“排序后的值”而是“排序所需的索引顺序”。这样做是用于通过索引重排原数组或多个关联数组实现间接排序并保持数据对齐。示例 2利用索引重排数组idx np.argsort(a, axis1) sorted_a np.take_along_axis(a, idx, axis1)print(sorted_a)输出[[1 2 3] [4 5 6]]说明argsort() 返回位置索引配合 take_along_axis() 可按该索引顺序重排数组。lexsort()通过对多个键进行稳定排序最后一个键优先实现字典序lexicographic order排序并返回对应的索引顺序。numpy.lexsort(keys, axis-1)参数说明• keys键序列 (k1, k2, ..., kn) 中最后一个键 kn 为主关键字前面的键依次作为次关键字• axis排序轴示例二维数据按多列排序a np.array([[1, 3], [2, 2], [1, 2]]) # keys 顺序a[:, 0] 为次关键字a[:, 1] 为主关键字最后一个键优先idx np.lexsort((a[:, 0], a[:, 1]))print(idx)print(a[idx])输出[2 1 0] [[1 2] [2 2] [1 3]]说明最后一个键优先排序相当于 SQLORDER BY col2, col1。排序过程基于稳定排序从低优先级到高优先级逐步完成。示例 2先按年龄排序再按姓名排序import numpy as np # 数据每行表示 (name, age)names np.array([Alice, Bob, Charlie, David])ages np.array([25, 20, 25, 20]) # 使用 lexsort最后一个键优先idx np.lexsort((names, ages)) print(idx)输出[1 3 0 2]说明lexsort() 的结果用于生成统一排序索引从而对多列数据进行一致的多关键字排序。根据索引重排数据sorted_names names[idx]sorted_ages ages[idx] print(sorted_names)print(sorted_ages)输出[Bob David Alice Charlie][20 20 25 25]三、部分排序partition()返回部分排序的数组。numpy.partition(a, kth, axis-1, kindintroselect)参数说明• a输入数组• kth第 k 个位置0-based• axis操作轴• kind选择算法introselect默认选择算法快速选择 堆排序混合函数行为说明1、选择一个目标位置 kth2、通过选择算法introselect找到该位置的正确元素3、将数组划分为两部分左侧 ≤ a[kth]右侧 ≥ a[kth]partition() 不是完全排序而是定位第 k 小元素并完成一次分区操作。示例 1一维数组a np.array([7, 2, 5, 4, 9, 1]) b np.partition(a, 2)print(b)输出示意[1 2 4 7 9 5]说明位置 2 上是第 3 小元素左侧元素都不大于它右侧元素都不小于它。左右内部不保证有序。示例 2二维数组沿指定轴a np.array([[7, 2, 5], [4, 9, 1]]) b np.partition(a, kth1, axis1)print(b)输出示意[[2 5 7] [1 4 9]]说明对每一行分别执行 partition() 操作。这里 kth1 表示每一行中第 2 小的元素应被放在索引位置 1 上。因此第 0 行 [7, 2, 5] 中第 2 小元素是 5第 1 行 [4, 9, 1] 中第 2 小元素是 4同时只保证该位置左侧元素都不大于它该位置右侧元素都不小于它。左右两部分内部不保证有序因此结果不一定是完全排序后的数组。partition() 的结果不唯一只保证第 kth 元素位置正确及左右分区关系。argpartition()返回部分排序的索引。numpy.argpartition(a, kth, axis-1)参数说明同 partition。示例 1找出最小的 3 个元素a np.array([9, 1, 5, 3, 7, 2, 8]) idx np.argpartition(a, 2) # 最小的 3 个元素所在位置无序 print(idx)print(a[idx[:3]])输出示意[1 5 3 2 4 0 6][1 2 3]示例 2每行最小两个元素a np.array([[7, 2, 5], [4, 9, 1]]) idx np.argpartition(a, kth1, axis1) # 取最小两个元素np.take_along_axis(a, idx[:, :2], axis1)输出[[2 5] [1 4]]说明返回的是每行最小两个元素但内部顺序不一定有序。argpartition() 用于高效获取 Top-K 元素的索引避免完整排序时间复杂度接近 O(n)。四、搜索定位searchsorted()在有序数组中查找插入位置。返回插入位置索引。numpy.searchsorted(a, v, sideleft, sorterNone)参数说明• a一维有序数组• v待插入值• side插入位置策略left插入到最左侧位置right插入到最右侧位置• sorter排序索引说明searchsorted() 基于二分查找用于保持数组有序。示例 1在一维有序数组中查找从二维中取一行a np.array([[1, 3, 5], [2, 4, 6]]) np.searchsorted(a[0], 4) # 2示例 2side 参数np.searchsorted([1, 2, 2, 3], 2, sideleft) # 1np.searchsorted([1, 2, 2, 3], 2, sideright) # 3示例 3插入元素并保持数组有序a np.array([1, 3, 5, 7]) # 查找插入位置pos np.searchsorted(a, 4)b np.insert(a, pos, 4) print(b)输出[1 3 4 5 7]五、去重与统计unique()返回数组中的唯一元素数组可附加索引或计数。numpy.unique(ar, return_indexFalse, return_inverseFalse, return_countsFalse, axisNone)参数说明• ar输入数组• return_index是否返回原始索引• return_inverse是否返回重建索引• return_counts是否返回出现次数• axis按轴去重示例一维去重a np.array([1, 2, 2, 3, 3, 3]) np.unique(a, return_countsTrue)输出(array([1, 2, 3]), array([1, 2, 3]))说明第一个数组 [1, 2, 3] 表示去重后的唯一元素按升序排列。第二个数组 [1, 2, 3] 表示对应每个元素的出现次数。示例 2二维数组沿行轴去重a np.array([[1, 2], [1, 2], [2, 3]]) np.unique(a, axis0)输出[[1 2] [2 3]]说明unique(axis0) 将每一行视为一个元素去重后按字典序返回唯一行。示例 3返回索引信息values, indices np.unique(a, axis0, return_indexTrue)print(values)print(indices)输出[[1 2] [2 3]][0 2] 小结NumPy 提供了完整的排序与搜索函数体系sort() 与 argsort() 分别用于值排序与索引排序partition() 与 argpartition() 用于高效的部分排序searchsorted() 用于有序数组定位unique() 用于去重与统计。不同函数在排序完整性、返回形式及性能方面存在差异应根据任务需求合理选择。“点赞有美意赞赏是鼓励”