我想按行索引二维矩阵并重新分配值。
例如,首先考虑一维矢量情况,其中我们有三个具有相同形状的一维张量t1, indexes, t2
。我们可以按以下步骤进行索引和重新分配:
indexes = torch.tensor([0, 2, 1, 3])
t1 = torch.tensor([0.0, 0.0, 0.0, 0.0])
t2 = torch.tensor([0.1, 0.2, 0.3, 0.4])
t1[indexes] = t2
现在,假设t1, indexes, t2
是2D矩阵而不是1D向量,并且具有相同的形状(R X C)
。我想对这些矩阵中的每一行进行与上述类似的索引编制:
for i in range(R):
t1[i][indexes[i]] = t2[i]
我想向量化此操作,而不是使用for循环。我该怎么做?
答案 0 :(得分:1)
因此,为了进行multi-index
选择,可以使用torch.gather函数,该函数沿dim(第二个参数)指定的轴收集值。
示例1:
t2 = torch.tensor([[0.1, 0.2, 0.3, 0.4],
[0.8, 1.8, 0.2, 0.3],
[0.5, 0.1, 0.2, 0.4]])
indexes1 = torch.tensor([[0, 2, 0, 2],
[0, 1, 1, 0],
[0, 0, 1, 2]])
t1 = torch.gather(t2, 0, indexes1) # dim is 0
print(t1)
输出:
tensor([[0.1000, 0.1000, 0.3000, 0.4000],
[0.1000, 1.8000, 0.2000, 0.4000],
[0.1000, 0.2000, 0.2000, 0.4000]])
示例2:
t2 = torch.tensor([[0.1, 0.2, 0.3, 0.4],
[0.8, 1.8, 0.2, 0.3],
[0.5, 0.1, 0.2, 0.4]])
indexes2 = torch.tensor([[0, 3, 2, 0],
[0, 1, 1, 3],
[0, 0, 3, 2]])
t1 = torch.gather(t2, 1, indexes2) # dim is 1
print(t1)
输出:
tensor([[0.1000, 0.4000, 0.3000, 0.1000],
[0.8000, 1.8000, 1.8000, 0.3000],
[0.5000, 0.5000, 0.4000, 0.2000]])
要了解有关torch.gather
函数的更多信息,只需进行this SO讨论。
您也可以使用torch.Tensor.scatter_
进行相同的操作。
t1.scatter_(0, indexes, t2)
基本上是说将t2
张量的元素发送到indexes
张量中的以下索引(在t1
张量中指定),行方向(维度0)。
示例:
t1 = torch.zeros((3, 4))
t2 = torch.tensor([[0.1, 0.2, 0.3, 0.4],
[0.8, 1.8, 0.2, 0.3],
[0.5, 0.1, 0.2, 0.4]])
indexes = torch.tensor([[1, 2, 0, 2],
[0, 1, 2, 1],
[2, 0, 1, 0]])
t1 = t1.scatter_(0, indexes, t2)
print(t1)
输出:
tensor([[0.8000, 0.1000, 0.3000, 0.4000],
[0.1000, 1.8000, 0.2000, 0.3000],
[0.5000, 0.2000, 0.2000, 0.4000]])
您可以从here了解更多信息。
答案 1 :(得分:0)
类似于@Anubhav的回答,只是在scatter_
的维度上稍有变化,就可以了。来源:PyTorch Discussion
indexes = torch.tensor([[0, 2, 1, 3],
[1, 0, 3, 2]])
t1 = torch.zeros_like(indexes).float()
t2 = torch.tensor([[0.1, 0.2, 0.3, 0.4],
[0.5, 0.6, 0.7, 0.8]])
t1.scatter_(1, indexes, t2)