【问题标题】:Vectorizing numpy code向量化 numpy 代码
【发布时间】:2018-06-14 15:07:19
【问题描述】:

我正在尝试对以下代码进行矢量化 -

for i in range(imL.shape[0]):
    for j in range(imL.shape[1]):
        if j - disp[i][j] >= 0:
            imR[i, j - disp[i][j], :] = imL[i, j, :]

基本上,我想这样做 -

A[i, j - B[i, j], k] = C[i, j, k] for all (i, j, k)

我研究了布尔索引并想出了这个 -

tmp = np.arange(imR.shape[1])
tmp = np.repeat(tmp[np.newaxis, :], imR.shape[0], axis=0)
tmp = np.repeat(tmp[:, :, np.newaxis], imR.shape[2], axis=2)

imR[(tmp - disp) >= 0] = imL

但是,这会引发错误 -

TypeError: NumPy boolean array indexing assignment requires a 0 or 1-dimensional input, input has 3 dimensions

我相信整数索引是解决方案,但是,我无法提出任何建议。有没有办法有效地对其进行矢量化?

注意:imL 和 imR 是 N x M x 3 ndarrays。 disp 是一个 N x M ndarray。

【问题讨论】:

    标签: numpy vectorization numpy-ndarray


    【解决方案1】:

    您可以使用np.indices 简化临时索引数组的创建:

    i_indices, j_indices = np.indices(disp.shape)
    

    然后您可以使用自定义公式创建更新的索引数组:

    # j - B[i, k]
    new_j_ind = j_indices - disp
    

    在以下条件下将更新后的j 值替换为原始js:

    # if j - disp[i][j] < 0, keep original j index
    new_j_ind[new_j_ind < 0] = j_indices[new_j_ind < 0]
    

    并写入数组。

    # A[i, j - B[i, j] if j - B[i, j] > 0 else j, k] = C[i, j, k] for all (i, j, k)
    imR[i_indices, new_j_ind] = imL
    

    但请注意:如果[i, j - B[i, j]] 曾经映射到任何 (i, k) 的相同坐标,则此定义不明确。在 for 循环中定义明确(最后写入的值获胜),在 numpy 矢量化代码中则不是。

    【讨论】:

    • 感谢有关使用 np.indices 临时索引数组的提示。但是,imR[select] = imL[select] 这一步在语义上并不是我想要实现的。我相信它转化为A[i, j - B[i, j], k] = C[i, j - B[i, j], k] for all (i, j, k)。与 for 循环相比,它绝对不会给我相同的结果。
    • 确实,我误读了这个问题。最初提出的解决方案是A[i, j, k] = C[i, j, k] for all (i, j, k) where j - B[i, j] &gt; 0。我更新了答案。
    • 谢谢您,这非常有效。我不明白imR[i_indices, new_j_ind] = imL 中的索引是如何工作的。您能否指出一些我可能会进一步理解的资源?
    • 文档有几个很好的例子,你可以从那里开始:docs.scipy.org/doc/numpy-1.13.0/reference/…。我经常发现举一个简单的例子(比如文档中的例子)并在 iPython 会话中使用它很有帮助。
    猜你喜欢
    • 1970-01-01
    • 2021-12-07
    • 2018-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 2017-03-28
    相关资源
    最近更新 更多