如何用PyTorch生成另一张量中各元素首次出现位置的张量
如何用PyTorch生成另一张量中各元素首次出现位置的张量
嘿,我完全理解你的需求——面对大规模的1D整数张量,用纯Python循环生成目标张量肯定慢得让人头疼,毕竟GPU的优势就是要用来做这种并行化的高效计算嘛。下面给你一个基于PyTorch的GPU友好方案,完全避开循环,速度拉满:
高效实现思路
我们可以借助PyTorch内置的torch.unique函数,它能高效提取张量中的唯一元素,同时返回这些元素在原张量中第一次出现的索引。之后只需要把这些索引映射到目标张量的对应位置就行,全程都是PyTorch优化过的CUDA操作,不管CPU还是GPU都能快速运行。
完整代码示例
import torch def get_first_occurrence_tensor(t): # 先做简单的输入校验 assert t.dtype in (torch.int, torch.long), "输入张量必须是int/long类型哦" assert t.dim() == 1, "输入得是1D张量才行" max_val = t.max().item() # 初始化结果张量,用-1填充(表示该数值没在原张量里出现过) result = torch.full((max_val,), -1, dtype=t.dtype, device=t.device) # 获取唯一值和它们首次出现的索引 unique_values, first_indices = torch.unique(t, return_indices=True) # 把首次出现的索引赋值到结果张量的对应位置 result[unique_values] = first_indices return result # 来测试一下 if __name__ == "__main__": # CPU测试案例 t_cpu = torch.tensor([2, 1, 3, 1, 2, 4]) a_cpu = get_first_occurrence_tensor(t_cpu) print("CPU运行结果:", a_cpu) # 输出: tensor([-1, 1, 0, 2]) # GPU测试(如果有可用的CUDA设备) if torch.cuda.is_available(): t_gpu = t_cpu.cuda() a_gpu = get_first_occurrence_tensor(t_gpu) print("GPU运行结果:", a_gpu) # 输出: tensor([-1, 1, 0, 2], device='cuda:0')
关键细节说明
torch.unique的return_indices参数:这个参数是核心,它返回的第二个张量就是每个唯一元素在原张量中第一次出现的位置索引,完全符合我们的需求。- 默认值处理:初始化结果张量时用
-1填充,如果你需要对未出现的数值设置其他标记(比如0或者len(t)),直接修改torch.full的填充值就行。 - 设备自动对齐:结果张量会自动和输入张量保持相同的设备(CPU/GPU),不用手动来回转移数据。
为什么这个方案快?
- 没有Python循环:所有操作都是PyTorch底层优化的实现,在GPU上会利用CUDA的并行计算能力,处理百万级甚至更大的张量时,速度比纯Python循环快几个数量级。
- 内存高效:
torch.unique只处理原张量中的唯一元素,不会像one-hot编码那样在数值范围很大时占用巨量内存,适配性更强。
备注:内容来源于stack exchange,提问作者daqh
相关产品推荐
相关产品推荐

