np.argsort
本文是根据 python 自带的 np.argsort 代码示例整理总结,博主自认为目前应该是对该函数比较全面的一个解释介绍。若有不当之处请留言。
def argsort(a, axis=-1, kind='quicksort', order=None):"""返回对数组排序的索引。使用 “kind” 关键字指定的算法,沿给定轴,执行间接排序。它返回一个按给定轴排序的索引数组,该数组与 “a” 形状一样。参数-------a: array。待排序的数组。axis: int 或 None,可选。指定按照哪个轴排序。默认为 -1 (最后一个轴)。如果为 None,将会现将 array 拉平 flatten 之后再排序。kind: {'quicksort', 'mergesort', 'heapsort', 'stable'},可选。排序方法。order: str 或者 str 列表,可选。当 “a” 是定义了字段的数组时,此参数指定第一个、第二个等要比较的字段。单个字段可以指定为字符串,但不需要指定所有字段,但未指定的字段仍将按在数据类型中出现的顺序来排序。返回--------index_array:ndarray,int。沿指定轴对 “a” 排序得到的索引数组。如果 “a” 是一维的, “a[index_array]” 输出排序后的 “a”。更普遍地,“np.take_along_axis(a, index_array, axis=a)“” 总是会输出一个排序的 “a”,不考虑维度。See Also--------sort : Describes sorting algorithms used.lexsort : Indirect stable sort with multiple keys.ndarray.sort : Inplace sort.argpartition : Indirect partial sort. 示例--------一维数组>>> x = np.array([3, 1, 2])>>> np.argsort(x)array([1, 2, 0]) #很好理解,也就是说 x 数组中从小到大排序,依次是第 1 、2、0 个元素,即1,2,3。 二维数组>>> x = np.array([[0, 3], [2, 4], [5, 1]])>>> xarray([[0, 3],[2, 4],[5, 1]])>>> x.shape # x 3 行 2 列(3, 2)到此,可以将上述数组想象成 excel 中的常见数据小样,表格有 3 行 2 列。>>> x[0] # x 的第 0 行array([0, 3])>>> x[:, 0] # x 的第 0 列array([0, 2, 5])>>> y = np.argsort(x, axis=0) # 按照第 0 轴排序>>> yarray([[0, 2],[1, 0],[2, 1]])# 这里解释一下,直觉上第 0 轴应该是“行”,而非“列”,但是为什么排序结果是按照“列”排序的。# 第 0 轴的意思是,根据数据的第 0 维度看数据,也就是说,应该 x[0],x[1],x[2] 这样慢慢看下去,那么 # 其实,整体上也就是按照通俗理解的按照“列”的方向逐渐向“下”看的。所以,y 的结果是将 x 的每列排了序,且# 列与列之间独立>>> z = np.take_along_axis(x, y, axis=0) # 按照第 0 轴排序后的真正结果>>> zarray([[0, 1],[2, 3],[5, 4]])想象一下,很多时候我们最想要的其实是按照某一轴(行或列)排序后的结果,而不是索引。可以看出上述结果 z,第一行是 [0, 1] 而非最初 x 中的 [0, 3],也就是说,列与列之间互相独立排序,单独从某一行来看,可能已经失去了原始的搭配组合。>>> y = np.argsort(x, axis=1) # 按照第 1 轴排序>>> yarray([[0, 1],[0, 1],[1, 0]])# 类比下来,第 1 轴的意思是,根据数据的第 1 维度看数据,也就是说,应该 x[:, 0],x[:, 1],x[:, 2]# 这样慢慢看下去,那么其实,整体上也就是按照通俗理解的按照“行”的方向逐渐向“右”看的。所以,y 的结果是# 将 x 的每行排了序,且行与行之间独立。>>> z = np.take_along_axis(x, y, axis=1) # 按照第 1 轴排序后的真正结果>>> zarray([[0, 3],[2, 4],[1, 5]])可以看出上述结果 z,第一列是 [0, 2, 1] 而非最初 x 中的 [0, 2, 5],也就是说,行与行之间互相独立排序,单独从某一列来看,也已经失去了原始的搭配组合。N 维数组排序:>>> ind = np.unravel_index(np.argsort(x, axis=None), x.shape)>>> ind # ind 是个 tuple,含有的 array 数量等于 x 的第一个维度大小(在这里是 2),ind 的读# 法是,两个 array 顺序组合来读,举例x[0, 0],x[2, 1],x[1, 0] 等等(array([0, 2, 1, 0, 1, 2]), array([0, 1, 0, 1, 1, 0]))>>> x[ind] # same as np.sort(x, axis=None) # 得到的是对 x 的排序,默认从小到大,其实相当于将 N 维数组拉平为 1 维之后直接排序。array([0, 1, 2, 3, 4, 5]) 根据 keys 排序:>>> x = np.array([(1, 0), (3, 0), (1, 2)], dtype=[('x', '<i4'), ('y', '<i4')])# 上面这行注意写法已经改变,x 中 array 的内容是 3 个长度为 2 的tuple,注意 tuple 为不可修改对象,# 这样后续如何排序都不会修改 tuple。后面 dtype 的设置,类似于我们在 excel 表格中为每一列给一个表# 头“班级”、“姓名”等属性名。>>> xarray([(1, 0), (3, 0), (1, 2)], dtype=[('x', '<i4'), ('y', '<i4')]) >>> np.argsort(x, order=('x','y')) # 这里就类似于按照表头属性名排序,此行的意思是,优先按照'x' 排序,然后按照‘y’排序,且排序后的结果仍然# 保持每个 tuple 的内容不变。下面结果的意思是,3 个 tuple 的排序结果是第 0, 2, 1 这样的顺序。array([0, 2, 1]) >>> np.argsort(x, order=('y','x')) # 同理,依次按照‘y’,‘x’排序。array([0, 1, 2])"""