0

Suppose I have some random numpy array:

>>> x = np.random.randn(10, 4, 4)

So this can be viewed as 10 4x4 arrays. Now, I also have some coordinates with respect to each of these arrays:

>>> coords.shape
(10, 4, 4, 2)

and a particular element of this array might look like the following:

>>> coords[i][j][k]
array([ 2,  2])

Now, I'd like to create an array, y of size (10, 4, 4), where y[i][j][k] = x[coords[i][j][k]] if coords[i][j][k] is in bounds, and 0 otherwise.

I've tried doing something like the following:

>>> y = np.where(np.logical_and(
                 np.all(coords >= 0, axis = 3), 
                 np.all(coords <= 3, axis = 3)), 
                 x[tuple(coords)], 0)

But I can't quite get the broadcasting rules correct, and I'm getting errors.

For example, say we have,

>>> x = np.array([
                 [[1., 2.],
                  [4., 5.]],
                 [[6., 7.],
                  [8., 9.]]])

with,

>>> coords = np.array([
                       [[[0,-1], [0, 0]],
                        [[1, 1], [1, 0]]],
                       [[[1, 1], [1, 0]],
                        [[7, 2], [0, 0]]]
                      ])

Then, I'd somehow like to get

y = np.array([
             [[0., 1.],
              [5., 4.]],
             [[9., 8.],
              [0., 6.]]]) 

How can I achieve this in Python?

8
  • Won't np.where(mask,x,0) work where mask is the all mask? That is, you could have listed x instead of x[tuple(coords)] there? Commented Nov 5, 2017 at 13:34
  • So that just gives you x, except in those positions where the coords are out of bounds. Not x shuffled with respect to the new coordinates. Commented Nov 5, 2017 at 13:46
  • Didn't you mean [j][k] there at : if coords[i][j][j] is in bounds, a? Also, what shuffling are we talking about? Commented Nov 5, 2017 at 13:49
  • Edited to reflect your above comment. And coords can be thought of as a 'shuffle' of the elements, but some coordinates may occur twice, or not at all, so it may not be a true shuffle. Commented Nov 5, 2017 at 13:56
  • So, coords[i,j,k,0] is indexing into the second axis and coords[i,j,k,1] into the third axis of x? Commented Nov 5, 2017 at 14:01

1 Answer 1

1

Seems like a bit of adavnced-indexing work was needed and should work for generic n-dim cases -

m,n = x.shape[0], x.shape[-1]
mask = (coords < n).all((-1)) & (coords >=0).all((-1))
v_coords = np.where(mask[:,:,:,None],coords,0)
out = x[np.arange(m)[:,None,None], v_coords[...,0], v_coords[...,1]]
out[~mask] = 0
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.