Python 用索引索引张量的第二维

Python 用索引索引张量的第二维,python,indexing,pytorch,tensor,Python,Indexing,Pytorch,Tensor,我使用索引张量在张量中选择元素。下面的代码我使用索引0、3、2、1列表来选择11、15、2、5 >>> import torch >>> a = torch.Tensor([5,2,11, 15]) >>> torch.randperm(4) 0 3 2 1 [torch.LongTensor of size 4] >>> i = torch.randperm(4) >>> a[i] 11

我使用索引张量在张量中选择元素。下面的代码我使用索引0、3、2、1列表来选择11、15、2、5

>>> import torch
>>> a = torch.Tensor([5,2,11, 15])
>>> torch.randperm(4)

 0
 3
 2
 1
[torch.LongTensor of size 4]

>>> i = torch.randperm(4)
>>> a[i]

 11
 15
  2
  5
[torch.FloatTensor of size 4]
现在,我有

>>> b = torch.Tensor([[5, 2, 11, 15],[5, 2, 11, 15], [5, 2, 11, 15]])
>>> b

  5   2  11  15
  5   2  11  15
  5   2  11  15
[torch.FloatTensor of size 3x4]
现在,我想使用索引来选择列0、3、2、1。换句话说,我想要这样的张量

>>> b

 11  15   2   5
 11  15   2   5
 11  15   2   5
[torch.FloatTensor of size 3x4]
如果使用Pytork v0.1.12版 对于这个版本,没有一个简单的方法可以做到这一点。尽管pytorch承诺张量操纵与numpy完全相同,但仍有一些功能尚不具备。这是其中之一

通常,如果使用numpy阵列,则可以相对轻松地执行此操作。像这样

>>> i = [2, 1, 0, 3]
>>> a = np.array([[5, 2, 11, 15],[5, 2, 11, 15], [5, 2, 11, 15]])
>>> a[:, i]

array([[11,  2,  5, 15],
       [11,  2,  5, 15],
       [11,  2,  5, 15]])
但张量也会给你一个错误:

>>> i = torch.LongTensor([2, 1, 0, 3])
>>> a = torch.Tensor([[5, 2, 11, 15],[5, 2, 11, 15], [5, 2, 11, 15]])
>>> a[:,i]
错误:

TypeError:使用torch.LongTensor类型的对象索引张量。唯一受支持的类型是整数、切片、numpy标量和torch.LongTensor或torch.ByteTensor作为唯一参数

该类型错误告诉您的是,如果您计划使用LongTensor或ByteTensor进行索引,那么唯一有效的语法是
a[]
a[]
。除此之外的任何事情都不起作用

由于此限制,您有两种选择:

选项1:转换为numpy、permute,然后返回张量

>>> i = [2, 1, 0, 3]
>>> a = torch.Tensor([[5, 2, 11, 15],[5, 2, 11, 15], [5, 2, 11, 15]])
>>> np_a = a.numpy()
>>> np_a = np_a[:,i]
>>> a = torch.from_numpy(np_a)
>>> a

 11   2   5  15
 11   2   5  15
 11   2   5  15
[torch.FloatTensor of size 3x4]
选项2:将要排列的dim移动到0,然后执行此操作

您将要排列的dim(在您的情况下dim=1)移动到0,执行排列,然后将其移回。这有点麻烦,但它完成了任务

def hacky_permute(a, i, dim):
    a = torch.transpose(a, 0, dim)
    a = a[i]
    a = torch.transpose(a, 0, dim)
    return a
并像这样使用它:

>>> i = torch.LongTensor([2, 1, 0, 3])
>>> a = torch.Tensor([[5, 2, 11, 15],[5, 2, 11, 15], [5, 2, 11, 15]])
>>> a = hacky_permute(a, i, dim=1)
>>> a

 11   2   5  15
 11   2   5  15
 11   2   5  15
[torch.FloatTensor of size 3x4]

如果使用Pytork v0.2.0版 使用张量的直接索引现在可以在这个版本中使用。即

>>> i = torch.LongTensor([2, 1, 0, 3])
>>> a = torch.Tensor([[5, 2, 11, 15],[5, 2, 11, 15], [5, 2, 11, 15]])
>>> a[:,i]

 11   2   5  15
 11   2   5  15
 11   2   5  15
[torch.FloatTensor of size 3x4]

谢谢torch.transpose是我目前使用的解决方法。