对数组进行排序

已完成

到目前为止,我们刚刚访问和修改了 NumPy 数组。 作为数据专家,你还需要了解如何对数组数据进行排序。 排序通常是梳理数据结构(如概述数据点)的一种重要方法。

你可使用 Python 的内置 sortsorted 函数,但它们的工作效率远不如 NumPy 的 np.sort 函数。

np.sort 返回经过排序的数组,但不修改输入:

a = np.array([2, 1, 4, 3, 5])
np.sort(a)

输出为:

array([1, 2, 3, 4, 5])

若要就地对数组进行排序,请直接对数组使用 sort 方法:

a.sort()
print(a)

输出为:

[1 2 3 4 5]

一个相关函数是 argsort,它返回已排序元素的索引,而不是元素本身:

a = np.array([2, 1, 4, 3, 5])
b = np.argsort(a)
print(b)

输出为:

[1 0 3 2 4]

此结果的第一个元素提供最小元素的索引,第二个值提供第二小元素的索引,依此类推。 然后可以使用这些索引(通过花式索引)重新构建已排序的数组:

a[b]

输出为:

array([1, 2, 3, 4, 5])

沿行或列排序

NumPy 排序算法的一项有用功能是,可使用 axis 参数沿多维数组的特定行或列进行排序。 例如:

rand = np.random.RandomState(42)
table = rand.randint(0, 10, (4, 6))
print(table)

输出为:

[[6 3 7 4 6 9]
 [2 6 7 4 3 7]
 [7 2 5 4 1 7]
 [5 1 4 0 9 5]]

对表的每列进行排序:

np.sort(table, axis=0)

输出为:

array([[2, 1, 4, 0, 1, 5],
       [5, 2, 5, 4, 3, 7],
       [6, 3, 7, 4, 6, 7],
       [7, 6, 7, 4, 9, 9]])

对表的每行进行排序:

np.sort(table, axis=1)

输出为:

array([[3, 4, 6, 6, 7, 9],
       [2, 3, 4, 6, 7, 7],
       [1, 2, 4, 5, 7, 7],
       [0, 1, 4, 5, 5, 9]])

请记住,此方法将每一行或每一列视为独立的数组。 当执行此类排序时,行值或列值之间的任何关系都将丢失。

部分排序:分区

有时无需对整个数组进行排序。 有时只需在数组中查找 k 个最小值(通常是在查看数据点之间的距离时)。 NumPy 通过 np.partition 函数提供此功能。  np.partition 采用数组和数字 k。 结果是一个新数组,k 个最小值在分区左侧,其余值在右侧(按任意顺序):

arr = np.array([7, 2, 3, 1, 6, 5, 4])
np.partition(arr, 3)

输出为:

array([2, 1, 3, 4, 6, 5, 7])

请注意,生成的数组中的前三个值是数组中最小的三个值,其余的数组位置包含剩余的值。 在这两个分区中,元素顺序是任意的。

与排序类似,我们可以沿多维数组的任意轴进行分区:

np.partition(table, 2, axis=1)

输出为:

array([[3, 4, 6, 7, 6, 9],
       [2, 3, 4, 7, 6, 7],
       [1, 2, 4, 5, 7, 7],
       [0, 1, 4, 5, 9, 5]])

结果是一个数组,其中每行的前两个槽包含该行中最小的值。 其余值填充剩余的槽。

最后,正如有 np.argsort 来计算排序的索引,还有一个 np.argpartition 来计算分区的索引。 在下一节讨论 pandas 时,我们将看到该函数的实际应用。

要点

对数据进行排序是探索数据并回答相关问题的基本方式。 NumPy 中的排序算法提供了一种快速、计算效率高的方式,可通过细化的控制对大量数据进行排序。