4

I have a multidimensional numpy array with the shape (4, 2000). Each column in the array is a 4D element where the first two elements represent 2D positions.

Now, I have an image mask with the same shape as an image which is binary and tells me which pixels are valid or invalid. An entry of 0 in the mask highlights pixels that are invalid.

Now, I would like to do is filter my first array based on this mask i.e. remove entries where the position elements in my first array correspond to invalid pixels in the image. This can be done by looking up the corresponding entries in the mask and marking those columns to be deleted which correspond to a 0 entry in the mask.

So, something like:

import numpy as np
# Let mask be a 2D array of 0 and 1s
array = np.random.rand(4, 2000)
for i in range(2000):
 current = array[:, i]
 if mask[current[0], current[1]] <= 0:
 # Somehow remove this entry from my array.

If possible, I would like to do this without looping as I have in my incomplete code.

asked Feb 17, 2015 at 14:37
2
  • your statement is not clear enough. Commented Feb 17, 2015 at 14:41
  • I made some edits. Hope it is better now. Thanks for the heads up. Commented Feb 17, 2015 at 14:50

2 Answers 2

3

You could select the x and y coordinates from array like this:

xarr, yarr = array[0, :], array[1, :]

Then form a boolean array of shape (2000,) which is True wherever the mask is 1:

idx = mask[xarr, yarr].astype(bool)

mask[xarr, yarr] is using so-called "integer array indexing". All it means here is that the ith element of idx equals mask[xarr[i], yarr[i]].

Then select those columns from array:

result = array[:, idx]

import numpy as np
mask = np.random.randint(2, size=(500,500))
array = np.random.randint(500, size=(4, 2000))
xarr, yarr = array[0, :], array[1, :]
idx = mask[xarr, yarr].astype(bool)
result = array[:, idx]
cols = []
for i in range(2000):
 current = array[:, i]
 if mask[current[0], current[1]] > 0:
 cols.append(i)
expected = array[:, cols]
assert np.allclose(result, expected)
answered Feb 17, 2015 at 14:55
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! Works perfectly. Did not know I could do such indexing.
0

I'm not sure if I'm reading the question right. Let's try again!

You have an array with 2 dimensions and you want to remove all columns that have masked data. Again, apologies if I've read this wrong.

import numpy.ma as ma
a = ma.array((([[1,2,3,4,5],[6,7,8,9,10]]),mask=[[0,0,0,1,0],[0,0,1,0,0]])
a[:,-a.mask.any(0)] # this is where the action happens

the a.mask.any(0) identifies all columns that are masked into a Boolean array. It's negated (the '-' sign) because we want the inverse, and then it uses that array to remove all masked values via indexing.

This gives me an array:

[[1 2 5],[6 7 10]]

In other words, the array has all removed all columns with masked data anywhere. Hope I got it right this time.

answered Feb 17, 2015 at 15:20

2 Comments

It is not finding where array entries are zero. It was about finding for which array entries, the corresponding masked entries are zero and then filtering those entries out. Sorry that my question was not phrased clearly.
No worries - all my fault for not reading closer. I've had another attempt. I'd be pleased to know if it's what you're after or not.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.