Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.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 随着列索引的增加,PyTorch将值按行索引粘贴到张量中_Python_Pytorch - Fatal编程技术网

Python 随着列索引的增加,PyTorch将值按行索引粘贴到张量中

Python 随着列索引的增加,PyTorch将值按行索引粘贴到张量中,python,pytorch,Python,Pytorch,我有一个张量输出,我想在其中放入一些值。我知道每个值应该进入的行,但我没有描述列的索引张量。相反,如果有属于一行的k值,则它们应该放在第0、1、…、k-1列中。用一个例子也许可以更好地解释这一点: 导入火炬 n=4 最大值=5 输出=火炬零点(n,最大值) row_idx=火炬张量([0,0,0,0,1,1,2,2,3]) values=torch.arange(len(row_idx)).float()#值可以是任何东西,而不仅仅是arange #输出[??]=值 这里前4个值应该在[0,0

我有一个张量
输出
,我想在其中放入一些
。我知道每个值应该进入的行,但我没有描述列的索引张量。相反,如果有属于一行的
k
值,则它们应该放在第0、1、…、k-1列中。用一个例子也许可以更好地解释这一点:

导入火炬
n=4
最大值=5
输出=火炬零点(n,最大值)
row_idx=火炬张量([0,0,0,0,1,1,2,2,3])
values=torch.arange(len(row_idx)).float()#值可以是任何东西,而不仅仅是arange
#输出[??]=值
这里前4个值应该在[0,0]处输出。。。[0,3],[1,0],[1,1]处的下两个值,依此类推

我现在是这样做的

,counts=torch.unique(行\u idx,返回\u counts=True)
射程=火炬距离(最大)
col_idx=火炬.cat([range_[:c]用于计数中的c])
输出[行idx,列idx]=值
输出
有没有更有效的方法将这些值粘贴到适当的位置


(如果你能想出一个更好的标题,请随意推荐)

我认为你的解决方案具有线性时间复杂性。因此,我不确定是否可以进一步改进。然而,我认为你提供的解决方案是不正确的。让我举个例子

对于以下输入:

row_idx = torch.tensor([0, 0, 1, 0, 0, 1, 2, 2, 2, 3])
您的解决方案输出以下内容

tensor([[4., 1., 3., 3., 0.],
        [2., 5., 2., 0., 0.],
        [6., 7., 8., 0., 0.],
        [9., 0., 0., 0., 0.]])
但是,我认为您的预期产出是:

tensor([[0., 1., 3., 4., 0.],
        [2., 5., 0., 0., 0.],
        [6., 7., 8., 0., 0.],
        [9., 0., 0., 0., 0.]])
因此,我建议以下我认为是正确的解决方案

def helper(a):
    idx = a.cumsum(-1)
    id_arr = torch.ones(idx[-1], dtype=int)
    id_arr[0] = 0
    id_arr[idx[:-1]] = -a[:-1]+1
    return id_arr.cumsum(-1)

n = 4
max_cols = 5
output = torch.zeros(n, max_cols)
row_idx = torch.tensor([0, 0, 1, 0, 0, 1, 2, 2, 2, 3])
values = torch.arange(len(row_idx)).float()

count = torch.unique(row_idx, return_counts=True)[1]
col_idx = helper(count)[row_idx.argsort().argsort()]
output[row_idx, col_idx] = values
print(output)

更新

您只需向代码中添加一行代码,如下所示,即可使其正常工作

_, counts = torch.unique(row_idx, return_counts=True)
range_ = torch.arange(max_cols)
col_idx = torch.cat([range_[:c] for c in counts])
col_idx = col_idx[row_idx.argsort().argsort()] # <== UPDATE
output[row_idx, col_idx] = values
print(output)
,counts=torch.unique(行\u idx,返回\u counts=True)
射程=火炬距离(最大)
col_idx=火炬.cat([range_[:c]用于计数中的c])

col_idx=col_idx[row_idx.argsort()。不过,这是一个很好的机会。如果没有人在一点时间内发布更简单/更快的内容,我会接受这一点,因为它更一般。您是否使用
helper
而不是仅仅对行索引进行排序以避免成为O(n log n)?(我不知道PyTorch是否有基数排序)不,helper函数只是代码中前三行的替代品<代码>\uu,计数=torch.unique(行\u idx,返回\u计数=True);射程=火炬距离(最大值);col_idx=火炬.cat([range_[:c]表示计数中的c])
在代码中,如果您添加以下行:
col\u idx=col\u idx[row\u idx.argsort().argsort()]
,我认为这也适用于您。
_, counts = torch.unique(row_idx, return_counts=True)
range_ = torch.arange(max_cols)
col_idx = torch.cat([range_[:c] for c in counts])
col_idx = col_idx[row_idx.argsort().argsort()] # <== UPDATE
output[row_idx, col_idx] = values
print(output)