NumPy的排序有直接排序和间接排序。直接排序是对数据直接进行排序,间接排序是指根据一个或多个键值对对数据进行排序。直接排序使用sort(),间接排序使用argsort()和lexsort()。
argsort()和lexsort()
使用argsort()和lexsort(),可以在排序后,得到一个由整数构成的索引数组,索引表示排序后数据在原数组序列中的位置。
(1)argsort()间接排序
argsort()返回的是数据从小到大排序后的索引列表。在argsort()中,当axis=0时,按列排列;当axis=1时,按行排列。如果省略axis,默认按行排列。
import numpy as np
a = np.array([7, 9, 5, 2, 8, 4, 3, 1, 4, 3])
print("原数组:", a)
print("排序后:", a.argsort()) #最小是1,索引是7;次小是2;索引是3;最大是9,索引是1
# 返回数组索引排序
print("显示较大的5个数:", a[a.argsort()][-5:])
输出结果:
原数组: [7 9 5 2 8 4 3 1 4 3] 排序后: [7 3 6 9 5 8 2 0 4 1] 显示较大的5个数: [4 5 7 8 9]
(2)lexsort()间接排序
lexsort()使用涉及多个数组的多个键值对进行排序。例如,首先对A列中的数据进行排序,然后对B列中的数据进行排序:
import numpy as np
#先按surnames升序排序,再按first_names升序排序
>>> surnames = ('Smith ', 'Galilei', 'Smith ')
>>> first_names = ('Tom', 'John', 'Mary')
>>> ind = np.lexsort((first_names, surnames)) #排序结果为surnames中元素索引的数组
>>> ind
array([1, 2, 0])
>>> [surnames[i] + ", " + first_names[i] for i in ind]
['Galilei, John', 'Smith, Mary', 'Smith, Tom']
从结果可见,surnames中两个相同元素Smith的索引分别为0和2,排在最后,而“Smith”在first_names中对应的元素分别是Tom和Mary,将surnames中值相同的元素再按first_names中对应元素排序,最终得到surnames元素索引顺序1, 2, 0。
下面的示例采用表示A列和B列的两个数组a、b。在应用lexsort()时,先按A列然后按B列进行排序,排序结果为包含A列中元素索引的数组。
import numpy as np
a = [2,5,1,8,1] #表示A列
b = [9,0,3,2,0] #表示B列
ind = np.lexsort((b, a)) #先按A列然后按B列进行排序
print("ind", ind)
tmp = [(a[i], b[i])for i in ind]
print("tmp", tmp)
输出结果:
ind [4 2 0 1 3] tmp [(1, 0), (1, 3), (2, 9), (5, 0), (8, 2)]
从结果可见,a中最小的两个值“1”的索引分别是2和4。当A列值相同时按B列对应元素排序,B列索引为2和4的元素分别是3和0,所以最终排序后对应A列索引分别是4、2、0、1、3(而不是2、4、0、1、3),因此tmp是[(1, 0), (1, 3), (2, 9), (5, 0), (8, 2)]。
