如何无循环将Numpy数组src按索引数组idx映射复制到dst?
用Numpy高级索引实现无循环映射赋值
嘿,这事儿用Numpy的高级索引就能完美解决,完全不需要写任何循环,效率还极高!
核心思路
你提到的映射关系正好匹配Numpy的索引规则:
src扁平化后的第i个元素,对应idx[:,i]指向的dst位置(行是idx[0,i],列是idx[1,i])- Numpy支持直接用两个一维数组分别指定行和列索引,实现批量赋值
代码实现
import numpy as np # 你的原始数组 src = np.random.rand(320, 240) # 假设idx是已给定的2x(320*240)索引数组(这里只是示例生成) idx = np.random.randint(0, 400, size=(2, 320*240)) # 1. 初始化dst:如果不知道dst的形状,可以从idx里提取最大索引来确定 dst_shape = (np.max(idx[0]) + 1, np.max(idx[1]) + 1) dst = np.zeros(dst_shape) # 2. 核心赋值操作:一步完成映射 dst[idx[0], idx[1]] = src.ravel() # ravel比flatten高效,返回视图而非拷贝
关键细节说明
src.ravel():把二维的src扁平化为一维数组,和src.flatten()的区别是,ravel优先返回原数组的视图(内存不复制),只有在必要时才返回拷贝,效率更高。- 高级索引的匹配逻辑:
idx[0]是所有目标位置的行索引数组,idx[1]是对应列索引数组,Numpy会自动将src.ravel()[i]赋值给dst[idx[0][i], idx[1][i]],完全对应你要的映射关系。
特殊情况处理:重复索引
如果idx里有重复的位置(多个src元素要放到dst的同一个位置),直接赋值会导致后面的元素覆盖前面的。如果需要累加这些值,可以用np.add.at实现原子操作:
np.add.at(dst, (idx[0], idx[1]), src.ravel())
内容的提问来源于stack exchange,提问作者ASML
相关产品推荐
相关产品推荐

