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)]。