Python中嵌套列表构成的嵌套元组的两级排序实现
对嵌套numpy数组构成的元组执行两级排序的实现
问题描述
我有一个由嵌套numpy数组构成的元组,结构如下:
import numpy as np ip = (np.array([[[ 50, 73]], [[ 50, 107]], [[ 55, 108]], [[ 55, 121]], [[978, 87]], [[977, 86]], [[977, 73]]], dtype=np.int32), np.array([[[ 669, 3]], [[ 668, 4]], [[ 667, 4]], [[1033, 71]], [[1035, 69]], [[1035, 4]], [[ 848, 4]], [[ 847, 3]], [[ 813, 3]], [[ 718, 4]], [[ 717, 3]]], dtype=np.int32), np.array([[[ 17, 3]], [[ 16, 4]], [[ 0, 4]], [[ 0, 49]], [[197, 49]], [[197, 8]], [[ 84, 4]], [[ 83, 3]]], dtype=np.int32))
需要对该结构执行两级排序:
- 第一级:将主元组中的元素按照每个数组内所有子数组的第一个元素的最小值升序排列,排序后结果如下:
op = (np.array([[[ 17, 3]], [[ 16, 4]], [[ 0, 4]], [[ 0, 49]], [[197, 49]], [[197, 8]], [[ 84, 4]], [[ 83, 3]]], dtype=np.int32), np.array([[[ 50, 73]], [[ 50, 107]], [[ 55, 108]], [[ 55, 121]], [[978, 87]], [[977, 86]], [[977, 73]]], dtype=np.int32), np.array([[[ 669, 3]], [[ 668, 4]], [[ 667, 4]], [[1033, 71]], [[1035, 69]], [[1035, 4]], [[ 848, 4]], [[ 847, 3]], [[ 813, 3]], [[ 718, 4]], [[ 717, 3]]], dtype=np.int32), )
- 第二级:对第一级排序后的结果,按照每个数组内所有子数组的第二个元素的最小值升序排列,最终结果如下:
final_op = (np.array([[[ 17, 3]], [[ 16, 4]], [[ 0, 4]], [[ 0, 49]], [[197, 49]], [[197, 8]], [[ 84, 4]], [[ 83, 3]]], dtype=np.int32), np.array([[[ 669, 3]], [[ 668, 4]], [[ 667, 4]], [[1033, 71]], [[1035, 69]], [[1035, 4]], [[ 848, 4]], [[ 847, 3]], [[ 813, 3]], [[ 718, 4]], [[ 717, 3]]], dtype=np.int32), np.array([[[ 50, 73]], [[ 50, 107]], [[ 55, 108]], [[ 55, 121]], [[978, 87]], [[977, 86]], [[977, 73]]], dtype=np.int32) )
解决方案
实现思路
利用Python的sorted()函数配合numpy数组的索引取值,分别定义两级排序的依据key:
- 第一级排序:提取每个数组中所有子数组第一个元素的最小值作为排序key
- 第二级排序:提取每个数组中所有子数组第二个元素的最小值作为排序key
代码实现
import numpy as np # 原始输入 ip = (np.array([[[ 50, 73]], [[ 50, 107]], [[ 55, 108]], [[ 55, 121]], [[978, 87]], [[977, 86]], [[977, 73]]], dtype=np.int32), np.array([[[ 669, 3]], [[ 668, 4]], [[ 667, 4]], [[1033, 71]], [[1035, 69]], [[1035, 4]], [[ 848, 4]], [[ 847, 3]], [[ 813, 3]], [[ 718, 4]], [[ 717, 3]]], dtype=np.int32), np.array([[[ 17, 3]], [[ 16, 4]], [[ 0, 4]], [[ 0, 49]], [[197, 49]], [[197, 8]], [[ 84, 4]], [[ 83, 3]]], dtype=np.int32)) # 第一级排序:按每个数组子数组第一个元素的最小值升序 op = tuple(sorted(ip, key=lambda arr: arr[:, :, 0].min())) # 第二级排序:按每个数组子数组第二个元素的最小值升序 final_op = tuple(sorted(op, key=lambda arr: arr[:, :, 1].min())) # 打印验证结果 print("第一级排序结果:") for item in op: print(item) print("\n最终排序结果:") for item in final_op: print(item)
代码说明
arr[:, :, 0]:通过numpy索引提取数组中所有子数组的第一个元素,min()取该集合的最小值作为排序依据sorted()函数默认按升序排列,排序后将列表转为元组以保持原始结构类型- 两级排序独立执行,先完成第一级得到中间结果
op,再基于op执行第二级排序得到最终结果final_op
内容的提问来源于stack exchange,提问作者spectre
相关产品推荐
相关产品推荐

