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.

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)
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.

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

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.