经常使用python和numpy进行排序,但没有很好的总结,以至于每次遇到新问题是都要看一遍manual或网上找。说实话在网上找的好些都是参差不齐、断章取义。下面对这些做点基本总结。
网上关于python及numpy排序函数,感觉比较好的有:
1、https://www.runoob.com/numpy/numpy-sort-search.html
2、https://blog.csdn.net/haiyang_duan/article/details/79221458
3、https://docs.scipy.org/doc/numpy/reference/generated/numpy.sort.html#numpy.sort
一、python排序函数:sort、sorted
1、sort 是应用在 list 上的方法。
2、sorted 可以对所有可迭代的对象进行排序操作。
list 的 sort 方法返回的是对已经存在的列表进行操作,而内建函数 sorted 方法返回的是一个 新的 list,而不是在原来的基础上进行的操作。
在此列举一个sorted对元组中指定位置排序例子:
A=(('a',85),('b',75),('c',65),('d',95))
B=sorted(A,key=lambda x:x[1],reverse=True)
print B
输出为:[('d', 95), ('a', 85), ('b', 75), ('c', 65)]
在此例中,对A中元素按单元中的第二项逆向排序,这里主要使用了key关键字和lambda表达式。
二、numpy排序函数:sort、argsort、lexsort、partition
关于这几个函数只说sort的order使用,上述博客1和博客2在其他方面说的很好了,在此不赘述。
1、sort返回排序后的对象。
首先去官网看一下sort的定义:
numpy.
sort
(a, axis=-1, kind=None, order=None)[source]
Return a sorted copy of an array.
Parameters: | a : array_like Array to be sorted. axis : int or None, optional Axis along which to sort. If None, the array is flattened before sorting. The default is -1, which sorts along the last axis. kind : {‘quicksort’, ‘mergesort’, ‘heapsort’, ‘stable’}, optional Sorting algorithm. The default is ‘quicksort’. Note that both ‘stable’ and ‘mergesort’ use timsort or radix sort under the covers and, in general, the actual implementation will vary with data type. The ‘mergesort’ option is retained for backwards compatibility. Changed in version 1.15.0.: The ‘stable’ option was added. order : str or list of str, optional When a is an array with fields defined, this argument specifies which fields to compare first, second, etc. A single field can be specified as a string, and not all fields need be specified, but unspecified fields will still be used, in the order in which they come up in the dtype, to break ties. |
---|---|
Returns: | sorted_array : ndarray Array of the same type and shape as a. |
其他不做解释,在此只说明order这个参数的使用,order这个参数用来指明排序的方式。首先来看下order 的官方解释:
当a是一个带有域定义的数组时,这个order参数用来指明哪个域,首先去用于比较,哪个第二,等等,单个域能使用字符串去指定,并不是所有的域都需要去指定,但未指明的域仍然会按他们在dtype中的排列顺序被使用,以此这个全面的排序
从上面的说明来看,使用order之前必须要定义一个域,这个类似C++中的结构体。我们发现网上和官方给的例子都是这样的,并且这个只能对tuple排序而不能对list排序。下面举例说明
dt=np.dtype([('x1', '<i4'), ('y1', '<i4'),('x2', '<i4'), ('y2', '<i4')])
A=np.array([(4,2,3,7),(1,3,2,6),(1,3,1,9)],dtype=dt)
print A
B=np.sort(A,order=['x1','y1','x2','y2'])#['x1','y1','x2','y2']
print B
输出:
[(4, 2, 3, 7) (1, 3, 2, 6) (1, 3, 1, 9)]
[(1, 3, 1, 9) (1, 3, 2, 6) (4, 2, 3, 7)]
但下面使用list,就输出异常:
dt=np.dtype([('x1', '<i4'), ('y1', '<i4'),('x2', '<i4'), ('y2', '<i4')])
A=np.array([[4,2,3,7],[1,3,2,6],[1,3,1,9]],dtype=dt)
print A
B=np.sort(A,order=['x1','y1','x2','y2'])#['x1','y1','x2','y2']
print B
输出:
[[(4, 4, 4, 4) (2, 2, 2, 2) (3, 3, 3, 3) (7, 7, 7, 7)]
[(1, 1, 1, 1) (3, 3, 3, 3) (2, 2, 2, 2) (6, 6, 6, 6)]
[(1, 1, 1, 1) (3, 3, 3, 3) (1, 1, 1, 1) (9, 9, 9, 9)]]
[[(2, 2, 2, 2) (3, 3, 3, 3) (4, 4, 4, 4) (7, 7, 7, 7)]
[(1, 1, 1, 1) (2, 2, 2, 2) (3, 3, 3, 3) (6, 6, 6, 6)]
[(1, 1, 1, 1) (1, 1, 1, 1) (3, 3, 3, 3) (9, 9, 9, 9)]]
还有经过重新组织后的数组,不能直接运算:
dt=np.dtype([('x1', '<i4'), ('y1', '<i4'),('x2', '<i4'), ('y2', '<i4')])
A=np.array([(4,2,3,7),(1,3,2,6),(1,3,1,9)],dtype=dt)
print A
B=np.sort(A,order=['x1','y1','x2','y2'])#['x1','y1','x2','y2']
print B
C=np.array(B[1])-np.array(B[2])
print C
输出:
[(4, 2, 3, 7) (1, 3, 2, 6) (1, 3, 1, 9)]
[(1, 3, 1, 9) (1, 3, 2, 6) (4, 2, 3, 7)]
Traceback (most recent call last):
C=np.array(B[1])-np.array(B[2])
TypeError: ufunc 'subtract' did not contain a loop with signature matching types dtype([('x1', '<i4'), ('y1', '<i4'), ('x2', '<i4'), ('y2', '<i4')])
解决的方法是首先转化为list,即下面的操作。
dt=np.dtype([('x1', '<i4'), ('y1', '<i4'),('x2', '<i4'), ('y2', '<i4')])
A=np.array([(4,2,3,7),(1,3,2,6),(1,3,1,9)],dtype=dt)
print A
B=np.sort(A,order=['x1','y1','x2','y2'])#['x1','y1','x2','y2']
print B
C=np.array(list(B[1]))-np.array(list(B[2]))
print C
2、argsort返回排序后的对象的索引
用法和sort类似,只是返回东西不一样。