Mask an array by the index given from other array
Question:
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]
Answers:
res = [False] * len(a)
for idx in b:
res[idx] = True
or
[idx in b for idx in range(len(a))]
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)
It will be something like this:
c = []
for i, v in enumerate(a):
mask = True if i in b else False
c.append(mask)
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)
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]
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]
res = [False] * len(a)
for idx in b:
res[idx] = True
or
[idx in b for idx in range(len(a))]
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)
It will be something like this:
c = []
for i, v in enumerate(a):
mask = True if i in b else False
c.append(mask)
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)
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]