# Cleanest way to replace np.array value with np.nan by user defined index

One question about mask 2-d np.array data.

For example:

- one 2-d np.array value in the shape of 20 x 20.
- An index t = [(1,2),(3,4),(5,7),(12,13)]

How to mask the 2-d array value by the (y,x) in index?

Usually, replacing with np.nan are based on the specific value like y[y==7] = np.nan

On my example, I want to replace the value specific location with *np.nan*.

For now, I can do it by:

- Creating a new array value_mask in the shape of 20 x 20
- Loop the value and testify the location by
**(i,j) == t[k]** - If True, value_mask[i,j] = value[i,j] ;
*In verse*, value_mask[i,j] = np.nan

My method was too bulky especially for hugh data(3 levels of loops). Are there some efficiency method to achieve that? Any advice would be appreciate.

## Answers

You are nearly there.

You can pass arrays of indices to arrays. You probably know this with 1D-arrays.

With a 2D-array you need to pass the array a tuple of lists (one tuple for each axis; one element in the lists (which have to be of equal length) for each array-element you want to chose). You have a list of tuples. So you have just to "transpose" it.

t1 = zip(*t)

gives you the right shape of your index array; which you can now use as index for any assignment, for example: value[t1] = np.NaN

(There are lots of nice explanation of this trick (with zip and *) in python tutorials, if you don't know it yet.)

You can use np.logical_and

arr = np.zeros((20,20))

You can select by location, this is just an *example location*.

arr[4:8,4:8] = 1

You can create a mask the same shape as arr

mask = np.ones((20,20)).astype(bool)

Then you can use the np.logical_and.

mask = np.logical_and(mask, arr == 1)

And finally, you can replace the 1s with the np.nan

arr[mask] = np.nan