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)