NumPy 排序、条件刷选函数

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

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

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

import numpy as np

'''
numpy.sort()
numpy.sort() 函数返回输入数组的排序副本。

numpy.argsort()
numpy.argsort() 函数返回的是数组值从小到大的索引值。

numpy.lexsort()
numpy.lexsort() 用于对多个序列进行排序。把它想象成对电子表格进行排序,每一列代表一个序列,排序时优先照顾靠后的列。
应用场景:小升初考试,重点班录取学生按照总成绩录取。在总成绩相同时,数学成绩高的优先录取,在总成绩和数学成绩都相同时,按照英语成绩录取…… 这里,总成绩排在电子表格的最后一列,数学成绩在倒数第二列,英语成绩在倒数第三列。
'''

a = np.array([[3,7],[9,1]])
print ('数组是:')
print (a)
print ('\n')
print ('调用 sort() 函数:')
print (np.sort(a))
print ('\n')
print ('按列排序:')
print (np.sort(a, axis = 0))
print ('\n')
# 在 sort 函数中排序字段
dt = np.dtype([('name', 'S10'),('age', int)])
print(dt)
a = np.array([("raju",21),("anil",25),("ravi", 17), ("amar",27)], dtype = dt)
print ('数组是:')
print (a)
print ('\n')
print ('按 name 排序:')
print (np.sort(a, order = 'name'))
print ('\n')

x = np.array([4, 1, 2])
print ('数组是:')
print (x)
print ('\n')
print ('对 x 调用 argsort() 函数:')
y = np.argsort(x)
print (y)
print ('\n')
print ('以排序后的顺序重构原数组:')
print (x[y])
print ('\n')
print ('使用循环重构原数组:')
for i in y:
print (x[i], end=" ")
print ('\n')

a = [1,5,1,4,3,4,4]
b = [9,4,0,4,0,2,1]
ind = np.lexsort((b,a))
print(ind)
# b在前,a在后,即是先按照a的元素进行比较
# 如a中的最小值为两个1,其索引分别为0,2,再计较b中相应索引上的值,即9,0
# 对应的最小应是:1,0,而其对应的索引为2,所以排序后返回的结果第一个值为索引2
# 下一个最小应是:1,9,而其对应的索引为0,所以排序后返回的结果第一个值为索引0
# 以此类推...
print ([str(a[i]) + ", " + str(b[i]) for i in ind])

>>>

数组是:
[[3 7]
[9 1]]

调用 sort() 函数:
[[3 7]
[1 9]]

按列排序:
[[3 1]
[9 7]]
[('name', 'S10'), ('age', '<i4')]

数组是:
[(b'raju', 21) (b'anil', 25) (b'ravi', 17) (b'amar', 27)]

按 name 排序:
[(b'amar', 27) (b'anil', 25) (b'raju', 21) (b'ravi', 17)]

数组是:
[4 1 2]

对 x 调用 argsort() 函数:
[1 2 0]

以排序后的顺序重构原数组:
[1 2 4]

使用循环重构原数组:
1 2 4

[2 0 4 6 5 3 1]

['1, 0', '1, 9', '3, 0', '4, 1', '4, 2', '4, 4', '5, 4']

 

msort、sort_complex、partition、argpartition

函数 描述
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 指定算法沿着指定轴对数组进行分区

import numpy as np

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

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

partition(a) 分区排序
指定一个数,对数组进行分区

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

'''

a = np.array([3,4,9,1,0,15]);

print('msort:')
print(np.msort(a))
print('\n')

a = np.sort_complex([5, 3, 6, 2, 1])

print('sort_complex:')
print(a)
print('\n')

a = np.array([3, 4, 2, 1])

print('partition:')
print(np.partition(a, 3))
# 将数组 a 中所有元素(包括重复元素)从小到大排列,比第3小的放在前面,大的放在后面
print(np.partition(a, (1, 3)))
# 小于 1 的在前面,大于 3 的在后面,1和3之间的在中间
print('\n')

a = np.array([46, 57, 23, 39, 1, 10, 0, 120])
print('argpartition:')
#找到数组的第 3 小(index=2)的值和第 2 大(index=-2)的值
print(a[np.argpartition(a, 2)[2]])
print(a[np.argpartition(a, -2)[-2]])

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

>>>

msort:
[ 0 1 3 4 9 15]

sort_complex:
[1.+0.j 2.+0.j 3.+0.j 5.+0.j 6.+0.j]

partition:
[2 1 3 4]
[1 2 3 4]

argpartition:
10
57
10
23

import numpy as np

'''
numpy.argmax() 和 numpy.argmin()
numpy.argmax() 和 numpy.argmin()函数分别沿给定轴返回最大和最小元素的索引。
'''

a = np.array([[30,40,70],[80,20,10],[50,90,60]])
print ('数组是:')
print (a)
print ('\n')
print ('调用 argmax() 函数:')
print (np.argmax(a))
print ('\n')
print ('展开数组:')
print (a.flatten())
print ('\n')
print ('沿轴 0 的最大值索引:')
maxindex = np.argmax(a, axis = 0)
print (maxindex)
print ('\n')
print ('沿轴 1 的最大值索引:')
maxindex = np.argmax(a, axis = 1)
print (maxindex)
print ('\n')
print ('调用 argmin() 函数:')
minindex = np.argmin(a)
print (minindex)
print ('\n')
print ('展开数组中的最小值:')
print (a.flatten()[minindex])
print ('\n')
print ('沿轴 0 的最小值索引:')
minindex = np.argmin(a, axis = 0)
print (minindex)
print ('\n')
print ('沿轴 1 的最小值索引:')
minindex = np.argmin(a, axis = 1)
print (minindex)

>>>

数组是:
[[30 40 70]
[80 20 10]
[50 90 60]]

调用 argmax() 函数:
7

展开数组:
[30 40 70 80 20 10 50 90 60]

沿轴 0 的最大值索引:
[1 2 0]

沿轴 1 的最大值索引:
[2 0 1]

调用 argmin() 函数:
5

展开数组中的最小值:
10

沿轴 0 的最小值索引:
[0 1 1]

沿轴 1 的最小值索引:
[0 2 0]

import numpy as np

'''
numpy.nonzero()
numpy.nonzero() 函数返回输入数组中非零元素的索引。

numpy.where()
numpy.where() 函数返回输入数组中满足给定条件的元素的索引。

numpy.extract()
numpy.extract() 函数根据某个条件从数组中抽取元素,返回满条件的元素。
'''

a = np.array([[30,40,0],[0,20,10],[50,0,60]])

print ('数组是:')
print (a)
print ('\n')
print ('调用 nonzero() 函数:')
y = np.nonzero(a)
print (y)
print ('\n')
print ('满足条件的元素:')
print (a[y])
print ('\n')

x = np.arange(9.).reshape(3, 3)
print ('数组是:')
print (x)
print ('\n')
print ( '大于 3 的元素的索引:')
y = np.where(x > 3)
print (y)
print ('\n')
print ('使用这些索引来获取满足条件的元素:')
print (x[y])
print ('\n')

x = np.arange(9.).reshape(3, 3)
print ('数组是:')
print (x)
print ('\n')
# 定义条件, 选择偶数元素
condition = np.mod(x,2) == 0
print ('按元素的条件值:')
print (condition)
print ('\n')
print ('使用条件提取元素:')
print (np.extract(condition, x))

>>>

数组是:
[[30 40 0]
[ 0 20 10]
[50 0 60]]

调用 nonzero() 函数:
(array([0, 0, 1, 1, 2, 2], dtype=int32), array([0, 1, 1, 2, 0, 2], dtype=int32))

满足条件的元素:
[30 40 20 10 50 60]

数组是:
[[0. 1. 2.]
[3. 4. 5.]
[6. 7. 8.]]

大于 3 的元素的索引:
(array([1, 1, 2, 2, 2], dtype=int32), array([1, 2, 0, 1, 2], dtype=int32))

使用这些索引来获取满足条件的元素:
[4. 5. 6. 7. 8.]

数组是:
[[0. 1. 2.]
[3. 4. 5.]
[6. 7. 8.]]

按元素的条件值:
[[ True False True]
[False True False]
[ True False True]]

使用条件提取元素:
[0. 2. 4. 6. 8.]

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄