NumPy 教程(第 17 章):排序、条件搜索和计数函数

NumPy 提供了多种排序的方法。 这些排序函数实现不同的排序算法,每个排序算法的特征在于执行速度,最坏情况性能,所需的工作空间和算法的稳定性。 下表显示了三种排序算法的比较

种类速度最坏情况工作空间稳定性
‘quicksort’(快速排序)1O(n^2)0
‘mergesort’(归并排序)2O(n*log(n))~n/2
‘heapsort’(堆排序)3O(n*log(n))0

numpy.sort() 函数

返回输入数组的排序副本。函数格式如下:

numpy.sort(a, axis, kind, order)

参数说明:

  • a: 要排序的数组

  • axis: 沿着它排序数组的轴,如果没有数组会被展开,沿着最后的轴排序, axis=0 按列排序,axis=1 按行排序

  • kind: 默认为’quicksort’(快速排序)

  • order: 如果数组包含字段,则是要排序的字段

示例:

In [1]: import numpy as np

In [2]: num = np.array([[3,7],[9,1]])

In [3]: num
Out[3]:
array([[3, 7],
       [9, 1]])

In [4]: np.sort(num)
Out[4]:
array([[3, 7],
       [1, 9]])

In [5]: np.sort(num, axis=0)
Out[5]:
array([[3, 1],
       [9, 7]])

In [6]: dt = np.dtype([('name',  'S10'),('age',  int)])

In [7]: dt
Out[7]: dtype([('name', 'S10'), ('age', '<i8')])

In [8]: num = np.array([("raju",21),("anil",25),("ravi",  17),("amar",27)], dtype=dt)

In [9]: num
Out[9]:
array([(b'raju', 21), (b'anil', 25), (b'ravi', 17), (b'amar', 27)],
      dtype=[('name', 'S10'), ('age', '<i8')])

In [10]: print(num)
[(b'raju', 21) (b'anil', 25) (b'ravi', 17) (b'amar', 27)]

In [11]: np.sort(num, order='name')
Out[11]:
array([(b'amar', 27), (b'anil', 25), (b'raju', 21), (b'ravi', 17)],
      dtype=[('name', 'S10'), ('age', '<i8')])

In [12]: print(np.sort(num, order='name'))
[(b'amar', 27) (b'anil', 25) (b'raju', 21) (b'ravi', 17)]

numpy.argsort() 函数

返回的是数组值从小到大的索引值

In [1]: import numpy as np

In [2]: x = np.array([3,  1,  2])

In [3]: x
Out[3]: array([3, 1, 2])

In [4]: y = np.argsort(x)

In [5]: y
Out[5]: array([1, 2, 0])

In [6]: x[y]
Out[6]: array([1, 2, 3])

In [7]: for i in y:
   ...:     print (x[i], end=' ')
   ...:
1 2 3

numpy.lexsort() 函数

用于对多个序列进行排序。把它想象成对电子表格进行排序,每一列代表一个序列,排序时优先照顾靠后的列

In [1]: import numpy as np

In [2]: nm = ('raju', 'anil', 'ravi', 'amar')

In [3]: dv = ('f.y.', 's.y.', 's.y.', 'f.y.')

In [4]: ind = np.lexsort((dv, nm))

In [5]: ind
Out[5]: array([3, 1, 0, 2])

In [6]: [nm[i] + ', ' + dv[i] for i in ind]
Out[6]: ['amar, f.y.', 'anil, s.y.', 'raju, f.y.', 'ravi, s.y.']

上面传入 np.lexsort 的是一个tuple,排序时首先排 nm,顺序为:amar、anil、raju、ravi 。综上排序结果为 [3 1 0 2]

msortsort_complexpartitionargpartition
  • msort(a) 数组按第一个轴排序,返回排序后的数组副本。np.msort(a) 相等于 np.sort(a, axis=0)

  • sort_complex(a) 对复数按照先实部后虚部的顺序进行排序。

  • partition(a, kth[, axis, kind, order]) 指定一个数,对数组进行分区

  • argpartition(a, kth[, axis, kind, order]) 可以通过关键字 kind 指定算法沿着指定轴对数组进行分区

复数排序:

In [1]: import numpy as np

In [2]: np.sort_complex([5, 3, 6, 2, 1])
Out[2]: array([1.+0.j, 2.+0.j, 3.+0.j, 5.+0.j, 6.+0.j])

In [3]: np.sort_complex([1 + 2j, 2 - 1j, 3 - 2j, 3 - 3j, 3 + 5j])
Out[3]: array([1.+2.j, 2.-1.j, 3.-3.j, 3.-2.j, 3.+5.j])

partition() 分区排序:

In [4]: num = np.array([3, 4, 2, 1])

In [5]: np.partition(num, 3)
Out[5]: array([2, 1, 3, 4])

In [6]: np.partition(num, (1, 3))
Out[6]: array([1, 2, 3, 4])

找到数组的第 3 小(index=2)的值和第 2 大(index=-2)的值

In [7]: arr = np.array([46, 57, 23, 39, 1, 10, 0, 120])

In [8]: arr[np.argpartition(arr, 2)[2]]
Out[8]: 10

In [9]: arr[np.argpartition(arr, -2)[-2]]
Out[9]: 57

同时找到第 3 和第 4 小的值。注意这里,用 [2,3] 同时将第 3 和第 4 小的排序好,然后可以分别通过下标 [2] 和 [3] 取得

In [10]: arr[np.argpartition(arr, [2,3])[2]]
Out[10]: 10

In [11]: arr[np.argpartition(arr, [2,3])[3]]
Out[11]: 23

numpy.argmax()numpy.argmin() 函数

分别沿给定轴返回最大和最小元素的索引

In [1]: import numpy as np

In [2]: num = np.array([[30,40,70],[80,20,10],[50,90,60]])

In [3]: num
Out[3]:
array([[30, 40, 70],
       [80, 20, 10],
       [50, 90, 60]])

In [4]: np.argmax(num)
Out[4]: 7

In [5]: num.flatten()
Out[5]: array([30, 40, 70, 80, 20, 10, 50, 90, 60])

In [6]: # 沿轴 0 的最大值索引

In [7]: np.argmax(num, axis=0)
Out[7]: array([1, 2, 0])

In [8]: # 沿轴 1 的最大值索引

In [9]: np.argmax(num, axis=1)
Out[9]: array([2, 0, 1])

In [10]: np.argmin(num)
Out[10]: 5

In [11]: # 展开数组中的最小值

In [12]: num.flatten()[minindex]
Out[12]: 10

In [13]: # 沿轴 0 的最小值索引

In [14]: np.argmin(num, axis=0)
Out[14]: array([0, 1, 1])

In [15]: np.argmin(num, axis=1)
Out[15]: array([0, 2, 0])

numpy.nonzero() 函数

返回输入数组中非零元素的索引

In [1]: import numpy as np

In [2]: num = np.array([[30,40,0],[0,20,10],[50,0,60]])

In [3]: num
Out[3]:
array([[30, 40, 0],
[ 0, 20, 10],
[50, 0, 60]])

In [4]: np.nonzero(num)
Out[4]: (array([0, 0, 1, 1, 2, 2]), array([0, 1, 1, 2, 0, 2]))

numpy.where() 函数

返回输入数组中满足给定条件的元素的索引

In [1]: import numpy as np

In [2]: x = np.arange(9.).reshape(3, 3)

In [3]: x
Out[3]:
array([[0., 1., 2.],
       [3., 4., 5.],
       [6., 7., 8.]])

In [4]: y = np.where(x > 3)

In [5]: y
Out[5]: (array([1, 1, 2, 2, 2]), array([1, 2, 0, 1, 2]))

In [6]: x[y]
Out[6]: array([4., 5., 6., 7., 8.])

numpy.extract() 函数

根据某个条件从数组中抽取元素,返回满条件的元素

In [1]: import numpy as np

In [2]: x = np.arange(9.).reshape(3, 3)

In [3]: x
Out[3]:
array([[0., 1., 2.],
       [3., 4., 5.],
       [6., 7., 8.]])

In [4]: y = np.mod(x, 2) == 0

In [5]: y
Out[5]:
array([[ True, False,  True],
       [False,  True, False],
       [ True, False,  True]])

In [6]: np.extract(y, x)
Out[6]: array([0., 2., 4., 6., 8.])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值