numpy数组元素变换前后的索引变化映射高效获取方法求助
问题1:高效实现方案
你原来的双层循环时间复杂度是O(len(x1)len(x2)),30~50万量级下运算量会达到千亿级,必然超时。最优方案的时间复杂度可以降到O(len(x1)+len(x2))*,两种成熟实现可选:
方案1:字典映射法(速度最快,实现最简单)
利用x2元素无重复的特性,先遍历一次x2生成值到索引的查找字典,再遍历一次x1直接查表即可:
import numpy as np # 第一步:生成x2的值-索引映射字典 val_to_idx = {v: i for i, v in enumerate(x2)} # 第二步:遍历x1查表生成T,找不到元素填np.nan T = [val_to_idx.get(v, np.nan) for v in x1] # 若需要numpy数组格式直接转换即可 T = np.array(T, dtype=np.float64)
你给出的示例用该代码运行结果为[3, 2, nan, 1],完全符合预期,30~50万量级下全程运行耗时不会超过1秒,远低于1分钟的性能要求。
方案2:numpy向量化实现(适合全程使用numpy数组的场景)
如果不想转Python列表,可以用numpy内置函数实现向量化运算:
# 先对x2排序,同时记录对应原始索引 sorter = np.argsort(x2) sorted_x2 = x2[sorter] # 查找x1元素在排序后x2中的位置 pos = np.searchsorted(sorted_x2, x1) # 处理越界情况 pos[pos == len(sorted_x2)] = 0 # 匹配校验掩码 mask = sorted_x2[pos] == x1 # 生成结果数组 T = np.full(len(x1), np.nan) T[mask] = sorter[pos[mask]]
该方案时间复杂度为O((len(x1)+len(x2))log len(x2)),同样远快于双层循环。
问题2:技术正式名称
这类操作的正式名称是索引映射(Index Mapping),也常被称为值到索引查找表构建,属于序列对齐类操作的一种,在数据清洗、多序列匹配场景中非常常见。
内容的提问来源于stack exchange,提问作者yvrob
相关产品推荐
相关产品推荐

