一次替换张量中的多个值的推荐方法?

Recommended way to replace several values in a tensor at once?

是否有一种批量方法可以在没有 for 循环的情况下一次替换 pytorch 张量中的几个特定值?

示例:

old_values = torch.Tensor([1, 2, 3, 4, 5, 5, 2, 3, 3, 2])
old_new_value = [[2,22], [3,33], [6, 66]]

old_new_value = [[2,22], [3,33], [6, 66]],意思是2应该换成22,3应该换成33,6换成66

我可以有一个有效的方法来实现以下end_result吗?

end_result = torch.Tensor([1, 22, 33, 4, 5, 5, 22, 33, 33, 22])

请注意 old_values 不是唯一的。此外,old_new_value 中可能有一对 old_values 中不存在的对 (6, 66)。 此外,old_new_values 包含唯一行,

如果您的输入张量中没有任何重复元素,这是使用 掩码 和使用 基本索引[=23= 赋值的一种简单方法]. (我假设输入张量的数据类型是 int。但是,您可以直接将此代码改编为其他 dtype)。下面是一个可复制的插图,解释散布在行内注释中。

# input tensors to work with
In [75]: old_values    
Out[75]: tensor([1, 2, 3, 4, 5], dtype=torch.int32)

In [77]: old_new_value      
Out[77]:
tensor([[ 2, 22],
        [ 3, 33]], dtype=torch.int32)

# generate a boolean mask using the values that need to be replaced (i.e. 2 & 3)
In [78]: boolean_mask = (old_values == old_new_value[:, :1]).sum(dim=0).bool() 

In [79]: boolean_mask 
Out[79]: tensor([False,  True,  True, False, False])

# assign the new values by basic indexing
In [80]: old_values[boolean_mask] = old_new_value[:, 1:].squeeze() 

# sanity check!
In [81]: old_values 
Out[81]: tensor([ 1, 22, 33,  4,  5], dtype=torch.int32)

效率小记:整个过程中,我们没有对数据进行任何拷贝(即我们只对新的视图进行操作 通过根据我们的需要按摩形状)。因此,运行时间将非常快。

不确定是否还有人关心这个问题,但以防万一,这里有一个在 old_values 不唯一时也有效的解决方案:

mask = old_values == old_new_value[:, :1]
new_values = (1 - mask.sum(dim=0)) * old_values + (mask * old_new_value[:,1:]).sum(dim=0)

掩码的工作方式与@kmario23 的解决方案相同,但掩码会与新值相乘,然后求和以在所有正确的替换位置以新值结束。负掩码应用于旧值以在所有其他位置使用旧值。然后将两个掩码张量相加以获得所需的结果。