0

I have three numpy arrays, one the source array, one destination array and one mask array. I want to replace the values in the destination with the same values from the source only at the places where the mask is equal to one.

My naiive try was:

import numpy as np
destination = np.arange(9).reshape((3,3))
source = np.ones((3,3))
mask = np.zeros((3,3)).astype(np.uint8)
mask[1,1]=1

destination[mask] = source[mask]

which leads me to destination being

[[1, 1, 1],
 [1, 1, 1],
 [6, 7, 8]]

whereas I expect it to be

[[0, 1, 2],
 [3, 1, 5],
 [6, 7, 8]].

I do get the correct result, when I do

destination[mask==1] = source[mask==1].

My question is: Why are these two commands not identical, or what does the first even do?

4
  • Why are using np.uint8 for a mask? Shouldn't that be a boolean array? Commented May 27, 2019 at 11:31
  • Check what source[mask] is giving you Commented May 27, 2019 at 11:33
  • Fair, if I cast it to boolean, it does what it should. But my question remains, what does my first version actually do? Commented May 27, 2019 at 11:40
  • @Divakar I came from this side, and understanding what's going on is exactly the problem I have, hence asking this question. Commented May 27, 2019 at 11:53

1 Answer 1

1

First you must check inside the matrices and which matrix gives you what you want.

mask

Output

[[0, 0, 0],
 [0, 1, 0],
 [0, 0, 0]]

but destination[mask == 1] gives you a boolean matrix

mask == 1 

Output

[[False, False, False],
 [False,  True, False],
 [False, False, False]]

whereas:

destination[mask]

Output

[[[0, 1, 2],
  [0, 1, 2],
  [0, 1, 2]]

[[0, 1, 2],
 [3, 4, 5],
 [0, 1, 2]],

[[0, 1, 2],
 [0, 1, 2],
 [0, 1, 2]]]

but using destination[mask == 1] gives you a single value which is 4. It's the same for the source[mask == 1] which gives you the single value 1.

and if you use destination[mask==1] = source[mask==1] instead of destination[mask] = source[mask] you will only change the value 4 in the destination matrix.

I hope my explanation is clear.

Edit:

I hope I understand your question correct:

The simple integer indexing structure x[[i]] gives you the i'th row of the matrix.

So destination[0,1,2] gives:

[[0, 1, 2],
 [3, 4, 5],
 [6, 7, 8]]

and for an understandable example the input destination[1,2,0] leads to

[[3, 4, 5],
 [6, 7, 8],
 [0, 1, 2]]
Sign up to request clarification or add additional context in comments.

2 Comments

Yes this helps. I still have to figure what the integer indexing together with broadcasting really is doing, but this put me in the right direction.
Thank you so much. I edited your answer for better readability but now it makes sense to me. So, I was taking lines from my original matrix and because my index-space is a 3-tuple broadcasting to a 3-D matrix happens.

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.