5

I have the following arrays:

a = [10, 31, 30, 11, 17, 12, 22, 25, 85, 17, 21, 43]
b = [0, 1, 4, 6]

I want to mask a based on the index given by array b. That means getting:

c = [True, True, False, False, True, False, True, False, False, False, False, False]
1
  • 1
    Look into np.arange and np.in1d funcs. Commented Jul 5, 2016 at 22:49

5 Answers 5

3
In [524]: a=np.array([10, 31, 30, 11, 17, 12, 22, 25, 85, 17, 21, 43])
In [525]: b=np.array([0, 1, 4, 6])

To make a boolean c that is True at the b indices, just use:

In [526]: c=np.zeros(a.shape, bool)
In [527]: c[b]=True

In [528]: c
Out[528]: 
array([ True,  True, False, False,  True, False,  True, False, False,
       False, False, False], dtype=bool)

Then you can select the values of a with:

In [529]: a[c]
Out[529]: array([10, 31, 17, 22])

but you could just as well select them with b:

In [530]: a[b]
Out[530]: array([10, 31, 17, 22])

but c is better for removing those, a[~c]. np.delete(a,b) does the same thing.

Other array methods of generating c are

np.in1d(np.arange(a.shape[0]),b)
np.any(np.arange(a.shape[0])==b[:,None],0)

And since I was just discussing masked arrays in another question, I could do the same here:

In [542]: np.ma.MaskedArray(a,c)
Out[542]: 
masked_array(data = [-- -- 30 11 -- 12 -- 25 85 17 21 43],
             mask = [ True  True False False  True False  True False False False False False],
       fill_value = 999999)
Sign up to request clarification or add additional context in comments.

3 Comments

Am I doing something wrong or does this not work with 2D arrays?
@Yannic, I don't know what you doing or trying to do. But the masking that I demonstrated is easiest with 1d arrays. Somethings are different when working with 2+d arrays. If you are primarily trying to 'index', it would be a good idea to read the basic numpy documentation on the subject. It's a powerful concept, but it does take time to learn.
I found the solution here: zhangresearch.org/post/numpy-unravel-index You need to use "fancy indexing". First extract the column and row indices as separate lists like this: rows=coords[:,0] and cols=coords[:,1]. After that you can use arr[rows, cols] to get or modify multiple values in a 2d-array at once.
2

Use np.in1d on a new array created with np.arange from the length of a:

>>> a = [10, 31, 30, 11, 17, 12, 22, 25, 85, 17, 21, 43]
>>> b = [0, 1, 4, 6]
>>> a = np.array(a)
>>> b = np.array(b)
>>> np.in1d(np.arange(len(a)), b)
array([ True,  True, False, False,  True, False,  True, False, False,
       False, False, False], dtype=bool)

Comments

2

It will be something like this:

c = []
for i, v in enumerate(a):
    mask = True if i in b else False
    c.append(mask)

2 Comments

Thanks. Is there a way to return 'c' with the unmasked values of 'a' without changing its size?
You could append to c if False a tuple like (False, v) and should be it. Does that answer your question?
1
res = [False] * len(a)
for idx in b:
    res[idx] = True

or

[idx in b for idx in range(len(a))]

Comments

0

For anyone who wants to use this for 2D-arrays or N-dimensional arrays:

I found the solution here: https://zhangresearch.org/post/numpy-unravel-index

In case the link goes dead some time in the future here is the approach:

You have to use "fancy indexing"

>>> a = np.arange(20).reshape(4, 5)
>>> print(a)
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
>>> b = np.array([[0, 0], [0, 1], [0, 3], [1, 1], [2, 2]])
>>> print(b)
[[0 0]
 [0 1]
 [0 3]
 [1 1]
 [2 2]]
>>> b_x = b[:, 0]
>>> b_y = b[:, 1]
>>> print(b_x)
[0 0 0 1 2]
>>> print(b_y)
[0 1 3 1 2]

>>> print(a[b_x, b_y])
[ 0  1  3  6 12]

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.