Reputation: 13
I'm trying to vectorize the following code -
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, :]
Essentially, I want to do this -
A[i, j - B[i, j], k] = C[i, j, k] for all (i, j, k)
I looked into boolean indexing and came up with this -
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
However, this throws up the error -
TypeError: NumPy boolean array indexing assignment requires a 0 or 1-dimensional input, input has 3 dimensions
I believe integer indexing is the solution, however, I am unable to come up with anything. Is there a way to vectorize this efficiently?
NOTE: imL and imR are N x M x 3 ndarrays. disp is an N x M ndarray.
Upvotes: 1
Views: 121
Reputation: 11232
You can simplify the creation of a temporary indices array with np.indices:
i_indices, j_indices = np.indices(disp.shape)
Then you can create an updated index array with your custom formula:
# j - B[i, k]
new_j_ind = j_indices - disp
Replace the updated j
values with the original j
s on the condition:
# if j - disp[i][j] < 0, keep original j index
new_j_ind[new_j_ind < 0] = j_indices[new_j_ind < 0]
And write the array.
# 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
Careful though: this is not well defined if [i, j - B[i, j]]
ever map to the same coordinates for any (i, k). In the for loop it's well defined (the last written value wins), in the numpy vectorization code it is not.
Upvotes: 1