对数组进行排序
到目前为止,我们刚刚访问和修改了 NumPy 数组。 作为数据专家,你还需要了解如何对数组数据进行排序。 排序通常是梳理数据结构(如概述数据点)的一种重要方法。
你可使用 Python 的内置 sort 和 sorted 函数,但它们的工作效率远不如 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 中的排序算法提供了一种快速、计算效率高的方式,可通过细化的控制对大量数据进行排序。