我本质上是在寻找一种完全矢量化的方法来获取TensorB:[1, 2, 3, 9]
和TensorA:[1,2,3,3,2,1,4,5,9]
,对于TensorB中的每个值,找到它在TensorA中的索引位置,这样输出就像这样:[[0,5], [1,4], [2,3], [-1,8]]
个(尽管它是一维的也没问题,只要我能检索到哪个索引对应于TensorB中的哪个值的信息),其中每一行对应于TensorB中的一个值,其中列值是该给定值在A中出现的索引。
这种方法的工作原理是:
def vectorized_find_indices(A, B):
# Expand dimensions of A for broadcasting
A_expanded = A[:, None, None]
# Compare B with expanded A to create a boolean mask
mask = (B == A_expanded)
# Get the indices where A matches B
indices = torch.where(mask, torch.arange(A.size(0), device=A.device)[:, None, None], torch.tensor(-1, device=A.device))
# Reshape the indices to match the shape of B with an additional dimension for indices
result = indices.permute(1, 2, 0)
return result
字符串
但是我使用的Tensor太大了,无法进行广播,所以我受到的限制更大。
我也尝试了几种更简单的方法,比如searchsorted
,我找到了这个解决方案:(A[..., None] == B).any(-1).nonzero()
,这是接近但不够的,因为返回的索引不再直接附加到值。例如,上面的代码片段将返回:[0, 1, 2, 3, 4, 5, 8]
,这确实是找到匹配的正确索引,但是信息不再嵌套在第二维中,将其与相应的值联系起来,就像我需要的那样,但是我对pytorch很不熟悉,所以也许有可能以某种方式获取这些信息并使用这些信息重建它?
3条答案
按热度按时间wlp8pajw1#
我不确定是否有一种方法可以做到这一点,而不需要沿着B广播A或在B上执行for循环以减少内存开销。
一个解决方案可能是
字符串
或者在B上使用Python级别的循环:
型
lx0bsm1f2#
给定输入
B = np.array([1, 2, 3, 9])
和A = np.array([1,2,3,3,2,1,4,5,9])
,为了使算法完全可向量化,我会这样进行:将
indices
定义为形状为(len(B), len(A), 2)
的网格,以便对于每个i
和j
,indices[i,j] = [i, j]
:字符串
一旦你有了索引,你就可以过滤它们来检索所有满足
A[i]==B[j]
的对[i,j]
:型
这个矩阵中的每一行都是一对匹配元素的索引:例如
[0,0]
表示A[0]==B[0]
,[5,0]
表示A[5]==B[0]
,[8,3]
表示A[8]==B[3]
等等。一旦你有了这些数据,你就可以决定如何组织这些信息了。因为你想要的输出是像
[[0,5], [1,4], [2,3], [-1,8]]
这样的东西,我会使用为this question提出的group_by
矢量化函数,由@Carlos Pinzón编写:型
为了完整起见,我附上了
group_by
函数:型
gjmwrych3#
如果
A
和B
都是1D数组,并且您想要它们的公共值的索引,则可以广播相等检查,然后使用对应维度的OR折叠结果(这可以使用any
并指定轴来完成)。字符串