python及numpy排序函数的一点总结

经常使用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(aaxis=-1kind=Noneorder=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类似,只是返回东西不一样。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值