NumPy中如何将数组内一组值重映射为另一组指定值?
NumPy 双数组规则元素重映射最优方案
针对这类给定原始值集合、对应目标值集合的数组元素替换需求,NumPy生态下性能最好、实现最简洁的方案是查找表(LUT)索引法,全程走底层C层向量化运算,没有Python层面的循环开销,大数组场景下性能比逐值判断、循环替换高两个数量级以上。
预置测试数据
import numpy as np # 待重映射原始数组 test_array = np.array([1, 4, 2, 5, 7, 4, 2, 5, 6, 7, 7, 2, 5]) # 映射规则:map_from 与 map_to 位置一一对应 map_from = np.array([2, 4, 5]) map_to = np.array([9, 0, 3])
核心实现代码
# 1. 初始化查找表,默认值和下标保持一致,即不做替换 max_ele = test_array.max() lut = np.arange(max_ele + 1, dtype=test_array.dtype) # 2. 把需要替换的映射关系写入查找表 lut[map_from] = map_to # 3. 直接用原始数组作为索引取值,一步得到重映射结果 remaped_array = lut[test_array]
运行后得到的remaped_array输出为[1, 0, 9, 3, 7, 0, 9, 3, 6, 7, 7, 9, 3],和预期结果完全一致。
方案说明
- 适用场景:最适合标签类、取值为非负整数、最大值不会过大的数组,是这类场景下的首选方案
- 性能表现:时间复杂度O(n),和数组长度线性相关,没有额外冗余计算
- 扩展成本:后续新增映射规则只需要往
map_from、map_to中追加对应键值对即可,不需要修改核心逻辑
如果待处理数组包含负数、或者元素值跨度极大(比如存在百万以上的孤立大值,会导致查找表占用过多内存),可以使用通用向量化方案替代,性能同样远优于Python循环:
sorted_idx = np.argsort(map_from) sorted_from = map_from[sorted_idx] sorted_to = map_to[sorted_idx] pos = np.searchsorted(sorted_from, test_array) valid_mask = pos < len(sorted_from) valid_mask[valid_mask] = test_array[valid_mask] == sorted_from[pos[valid_mask]] remaped_array = test_array.copy() remaped_array[valid_mask] = sorted_to[pos[valid_mask]]
内容的提问来源于stack exchange,提问作者Nemanja Stojanovic
相关产品推荐
相关产品推荐

