NumPy - 数组排序
NumPy 中的数组排序
在 NumPy 中,排序是指将数组元素按特定顺序排列的过程,通常是升序或降序。
NumPy 提供了几个执行排序操作的函数,这些函数可以应用于一维数组和多维数组。它们如下:
- sort() 函数
- partition() 函数
- argsort() 函数
- lexsort() 函数
使用 np.sort() 函数
np.sort() 函数对数组元素进行排序,并返回一个包含排序后元素的新数组。除非使用"ndarray"对象的sort()函数进行排序,否则原始数组保持不变。
排序可以沿指定轴进行,如果未指定轴,则该函数默认沿最后一个轴排序。语法如下:
numpy.sort(a, axis=-1, kind=None, order=None)
其中:
- a: 待排序的数组。
- axis: 排序所沿的轴。默认值为 -1,表示沿最后一个轴排序。
- kind: 使用的排序算法。选项包括"快速排序"、"归并排序"、"堆排序"和"稳定排序"。
- order: 用于对结构化数组进行排序,定义要比较的字段。
示例
在以下示例中,我们使用 np.sort() 函数对给定数组进行升序排序 -
import numpy as np arr = np.array([3, 1, 2, 5, 4]) sorted_arr = np.sort(arr) print("原始数组:", arr) print("排序后数组:", sorted_arr)
以下是获得的输出 -
原始数组:[3 1 2 5 4] 排序后数组:[1 2 3 4 5]
NumPy 中的原地排序
原地排序是一种直接对原始数组执行排序操作的方法,它修改原始数组的顺序(默认为升序),而不创建单独的已排序副本。
在 NumPy 中,我们可以使用 ndarray 对象的 sort() 函数执行原地排序。语法如下:-
ndarray.sort(axis=-1, kind=None, order=None)
示例
在此示例中,我们使用 arr.sort() 函数对给定数组进行原地排序,并修改原始数组:-
import numpy as np arr = np.array([3, 1, 2, 5, 4]) arr.sort() print("原地排序数组:", arr)
这将产生以下结果:-
原地排序数组:[1 2 3 4 5]
沿特定轴排序
NumPy 允许沿多维数组中的特定轴对元素进行排序。它可以帮助您以尊重数组结构的方式组织数据,无论是对行、列还是高维切片进行排序。
我们可以使用 np.sort() 函数的 axis 参数沿 Numpy 中的特定轴对元素进行排序 -
- 轴 0: 它表示二维数组中的行(向下方向)。沿轴 0 排序会单独对每一列进行排序。
- 轴 1: 它表示二维数组中的列(水平方向)。沿轴 1 排序会单独对每一行进行排序。
- 更高维度:在维度超过二维的数组中,轴 2、轴 3 等对应于更高维度的切片。
示例
在下面的示例中,我们沿两个不同的轴对二维 NumPy 数组进行排序:轴 0(列)和轴 1(行)−
import numpy as np arr = np.array([[3, 2, 1], [6, 5, 4]]) sorted_arr_axis0 = np.sort(arr, axis=0) sorted_arr_axis1 = np.sort(arr, axis=1) print("原始数组: ", arr) print("沿轴 0 排序: ", sorted_arr_axis0) print("沿轴 1 排序: ", sorted_arr_axis1)
以下是上述代码的输出 -
原始数组: [[3 2 1] [6 5 4]] 沿轴 0 排序: [[3 2 1] [6 5 4]] 沿轴 1 排序: [[1 2 3] [4 5 6]]
使用partition()函数进行部分排序
NumPy中的np.partition()函数用于对数组中的元素进行重新排序,使得所有小于指定元素(称为"第k个元素")的元素移动到它之前,所有大于"第 k 个元素"的元素移动到它之后。
当你需要在不完全排序的情况下找到数组中第 k 个最小或最大元素时,此函数非常有用。语法如下:
numpy.partition(a, kth, axis=-1, kind='introselect', order=None)
其中,
- a: 是要分区的数组。
- kth: 是我们需要围绕其对数组进行分区的元素的索引。它可以是整数或整数序列。
- axis: 是沿着其对数组进行分区的轴。默认情况下,它设置为 -1,表示最后一个轴。
- kind: 这是要使用的选择算法。默认值为 'introselect',它是快速选择和中位数中值的混合体。
- order: 用于复杂数据类型,指定排序依据的字段。
示例
在此示例中,数组被分区,使得索引 2 处的元素的定位方式为:它之前的所有元素都小于或等于,而它之后的所有元素都大于或等于 -
import numpy as np arr = np.array([3, 1, 2, 5, 4]) partitioned_arr = np.partition(arr, 2) print("分区数组:", partitioned_arr)
获得的输出如下所示 -
分区数组:[1 2 3 5 4]
使用 argsort() 函数进行间接排序
NumPy 中的 np.argsort() 函数用于获取对数组进行排序的索引。np.argsort() 函数不返回排序后的数组本身,而是返回一个索引数组,该数组表示元素应按何种顺序排列以实现排序数组。
当您需要根据一个数组的排序顺序对另一个数组进行排序时,此函数非常有用。语法如下:
numpy.argsort(a, axis=-1, kind=None, order=None)
其中:
- a: 您要排序的数组。
- axis: 排序时所沿的轴。默认情况下,设置为 -1,即最后一个轴。
- kind: 要使用的排序算法。选项包括"quicksort"、"mergesort"、"heapsort"和"stable"。默认值为"quicksort"。
- order:用于复杂数据类型,指定排序依据的字段。
示例
在下面的示例中,我们使用 np.argsort() 函数获取对数组"arr"进行排序的索引。然后,我们使用这些索引将原始数组重新排列成其排序顺序 -
import numpy as np arr = np.array([3, 1, 2, 5, 4]) sorted_indices = np.argsort(arr) print("用于对数组进行排序的索引:", sorted_indices) print("使用索引对数组进行排序:", arr[sorted_indices])
执行上述代码后,我们得到以下输出 -
用于对数组进行排序的索引:[1 2 0 4 3] 使用索引对数组进行排序:[1 2 3 4 5]
结构化排序数组
NumPy 中的结构化数组允许您创建数组,其中每个元素可以包含多个字段,每个字段都有各自的数据类型。这类似于传统编程语言中的数据库表或记录,其中每个条目可以包含多种类型的数据。
您可以基于一个或多个字段对结构化数组进行排序。这在您想要根据特定条件对记录进行排序时非常有用。为此,您可以使用 NumPy 中的 np.sort() 函数,该函数接受 order 参数来指定要按哪些字段进行排序。
示例
在下面的示例中,我们按"age"字段对结构化数组"arr"进行排序 -
import numpy as np arr = np.array([('John', 25), ('Alice', 30), ('Bob', 22)], dtype=[('name', 'U10'), ('age', 'i4')]) sorted_arr = np.sort(arr, order='age') print("已排序的结构化数组: ", sorted_arr)
结果如下 -
已排序的结构化数组: [('Bob', 22) ('John', 25) ('Alice', 30)]
使用 lexsort() 函数进行字典顺序排序
np.lexsort() 函数使用一系列键执行间接排序。它接受一系列字段或列作为参数,并返回一个索引数组,该数组将根据这些键对输入数组进行排序。语法如下:
numpy.lexsort(keys, axis=-1)
其中:
- keys: 它是一个数组序列或单个数组,其中每个数组代表一个用于排序的键。键按提供的顺序排序,这意味着序列中的最后一个键是主键,倒数第二个键是辅助键,依此类推。
- axis: 它是排序的轴。默认情况下,它设置为 -1,表示最后一个轴。
示例
在此示例中,使用 np.lexsort() 函数首先根据姓名对数组进行排序,然后如果姓名相同,则按年龄排序。排序顺序基于字典顺序比较 -
import numpy as np names = np.array(['John', 'Alice', 'Bob']) ages = np.array([25, 30, 22]) sorted_indices = np.lexsort((ages, names)) print("字典顺序排序的索引:", sorted_indices) print("排序后的姓名和年龄:", names[sorted_indices], ages[sorted_indices])
我们得到如下所示的输出 -
字典顺序排序的索引:[1 2 0] 排序后的姓名和年龄: ['Alice' 'Bob' 'John'] [30 22 25]