Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Pyrotch argsort排序,张量中有重复元素_Python_Sorting_Machine Learning_Pytorch_Tensor - Fatal编程技术网

Python Pyrotch argsort排序,张量中有重复元素

Python Pyrotch argsort排序,张量中有重复元素,python,sorting,machine-learning,pytorch,tensor,Python,Sorting,Machine Learning,Pytorch,Tensor,我有一个向量a=[0,1,2,3,0,0,1,1,2,2,3,3]。我需要以一种递增的方式对它进行排序,以便它以有序的方式列出,并从中提取argsort。为了更好地解释这一点,我需要对A进行排序,使其返回B=[0,4,5,1,6,7,2,8,9,3,10,11]。但是,当我使用pyotch的torch.argsort(A)时,它返回B=[4,5,0,1,6,7,2,8,9,3,10,11] 我假设这样做的算法在我这边是无法控制的。有没有办法在不引入for循环的情况下实现这一点?这种操作是我的NN

我有一个向量
a=[0,1,2,3,0,0,1,1,2,2,3,3]
。我需要以一种递增的方式对它进行排序,以便它以有序的方式列出,并从中提取argsort。为了更好地解释这一点,我需要对A进行排序,使其返回
B=[0,4,5,1,6,7,2,8,9,3,10,11]
。但是,当我使用pyotch的
torch.argsort(A)
时,它返回
B=[4,5,0,1,6,7,2,8,9,3,10,11]

我假设这样做的算法在我这边是无法控制的。有没有办法在不引入for循环的情况下实现这一点?这种操作是我的NN模型的一部分,如果不有效地执行,将导致性能问题。谢谢

这里有一种方法:

  • 使用numpy.argsort()对numpy数组进行排序
  • 使用torch.from_numpy()将结果转换为张量

    导入火炬
    将numpy作为np导入
    A=[0,1,2,3,0,0,1,1,2,2,3,3]
    x=np.数组(A)
    y=torch.from_numpy(np.argsort(x,kind='mergesort'))
    打印(y)


这是一个纯粹的基于PyTorch的解决方案,它利用了。这将极大地促进基于GPU的实现/运行,如果我们必须切换回NumPy,
argsort
it,然后再转移回PyTorch(如其他方法所建议的),这是不可能的

一旦我们有了这个布尔张量,我们就可以通过在转换布尔张量后检查
1
的位置来找到所需的索引

这将为我们提供排序的
输入
索引
。因为我们只需要索引,所以我们可以通过索引最后一列(
1
-1
)来获取索引


以下是OP在评论中提供的另一个示例的结果:

In [55]: A_large = torch.tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9])

In [56]: boolean_large = A_large[:, None] == torch.unique(A_large)

In [57]: torch.nonzero(boolean_large.t())[:, -1]
Out[57]: 
tensor([ 0, 10, 11,  1, 12, 13,  2, 14, 15,  3, 16, 17,  4, 18, 19,  5, 20, 21,
         6, 22, 23,  7, 24, 25,  8, 26, 27,  9, 28, 29])

注意:与其他答案中提出的基于NumPy的解决方案不同,这里我们不必担心我们必须使用的排序算法的
种类,因为我们根本不使用任何排序。

您可以尝试使用
NumPy.argsort()
来查看它是否有效。我尝试使用
NumPy.sort([0,1,2,3,0,0,1,1,2,3,3]))
结果是
[0,4,5,1,6,7,2,8,9,3,10,11]
如您所愿。完美-谢谢!嗯,在我的例子中,当向量更大时,这似乎就失效了。以案例
A=[0112344567809001234344556677889]
为例,需要组织这样的
B=[01011112132141531634171819520262237242582627929]
。但是,np.argsort()返回:
[10,0,11,1,13,12,15,14,2,3,17,16,19,18,4,21,5,20,6,22,23,25,7,24,27,8,26,9,28,29]
。已解决:要使用的排序算法需要是kind='mergesort',而不是默认的'quicksort'@AnubhavSingh。虽然这种方法似乎可行,但我们可能会遇到性能问题,因为numpy无法使用GPU,而且在CPU和GPU之间来回复制张量也会带来开销。此外,您可能会失去自动添加的功能,这是真正的切肉刀。非常感谢。当我想使用GPU时,我没有考虑这个问题。
In [53]: torch.nonzero(boolean.t())[:, -1]
Out[53]: tensor([ 0,  4,  5,  1,  6,  7,  2,  8,  9,  3, 10, 11])
In [55]: A_large = torch.tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9])

In [56]: boolean_large = A_large[:, None] == torch.unique(A_large)

In [57]: torch.nonzero(boolean_large.t())[:, -1]
Out[57]: 
tensor([ 0, 10, 11,  1, 12, 13,  2, 14, 15,  3, 16, 17,  4, 18, 19,  5, 20, 21,
         6, 22, 23,  7, 24, 25,  8, 26, 27,  9, 28, 29])