如何矢量化 Python 中的这些嵌套循环?

How can I vectorize these nested loops in Python?

我正在尝试矢量化以下内容:

n = torch.zeros_like(x)
for i in range(x.shape[0]):
    for j in range(x.shape[1]):
        for k in range(x.shape[2]):
            n[i, j, k] = p[i, x[i, j, k], j, k]

我试过做类似

的事情
n = p[:, x, ...]

但我只是收到一个错误,提示我 运行 内存不足,这不是很有帮助。我认为这个问题是,它不是在正确的索引处获取 x 的值,而是试图索引整个 x,但我不确定如果这是问题我将如何解决这个问题。

这看起来是一个完美的用例,因为 broadcasted fancy indices. np.ogrid 在这里是一个很有价值的工具,或者您可以手动调整范围:

i, j, k = np.ogrid[:x.shape[0], :x.shape[1], :x.shape[2]]
n = p[i, x, j, k]

这个黑魔法之所以有效,是因为 ogrid returns 三个数组的索引广播成与 x 相同的形状。因此,p 的最终提取将具有该形状。在那之后索引是微不足道的。另一种写法是:

i = np.arange(x.shape[0]).reshape(-1, 1, 1)
j = np.arange(x.shape[1]).reshape(1, -1, 1)
k = np.arange(x.shape[2]).reshape(1, 1, -1)
n = p[i, x, j, k]