1

I have an array A. I have an another array which I call switch. Array switch, is an array of boolean values (and np.nan which correspond to location of np.nan 3 x 3 arrays in A) that determines which 3 x 3 array in A gets selected for an operation.

Example:

switch = np.array([ True, False, False, False, np.nan])

a = np.array([[[ 0.,  0.,  0.],
        [ 9.,  0.,  0.],
        [ 3., 15.,  0.]],

       [[ 0.,  0.,  0.],
        [ 9.,  0.,  0.],
        [ 3., 15.,  0.]],

       [[ 0., 27.,  0.],
        [ 0.,  0.,  0.],
        [12., 18.,  0.]],

       [[ 0.,  0.,  6.],
        [12.,  0., 27.],
        [ 0.,  0.,  0.]],

       [[ np.nan, np.nan, np.nan],
        [np.nan, np.nan, np.nan],
        [ np.nan, np.nan, np.nan]]])

The final selected array based on the example above should be:

np.array([[[ 0.,  0.,  0.],
            [ 9.,  0.,  0.],
            [ 3., 15.,  0.]],

       [[ np.nan, np.nan, np.nan],
        [np.nan, np.nan, np.nan],
        [ np.nan, np.nan, np.nan]],

       [[ np.nan, np.nan, np.nan],
        [np.nan, np.nan, np.nan],
        [ np.nan, np.nan, np.nan]],

       [[ np.nan, np.nan, np.nan],
        [np.nan, np.nan, np.nan],
        [ np.nan, np.nan, np.nan]],

       [[ np.nan, np.nan, np.nan],
        [np.nan, np.nan, np.nan],
        [ np.nan, np.nan, np.nan]]])

I can do this by using a for loop and iterating through each 3 x 3 array in A with the use of if/else control statements but I am wondering if there is a way to do this using the built in functionality within numpy. For loops and if/else statements is likely much slower than array manipulation. I've been tinkering but so far have not been able to find an optimal numpy solution.

I can restructure array switch but array A I cannot change the structure/shape.

2

2 Answers 2

1

You can use np.where:

out = np.where(switch[:,None,None], a, np.nan)

Or use masking:

out = a.copy()
out[switch!=True] = np.nan

Output:

array([[[ 0.,  0.,  0.],
        [ 9.,  0.,  0.],
        [ 3., 15.,  0.]],

       [[nan, nan, nan],
        [nan, nan, nan],
        [nan, nan, nan]],

       [[nan, nan, nan],
        [nan, nan, nan],
        [nan, nan, nan]],

       [[nan, nan, nan],
        [nan, nan, nan],
        [nan, nan, nan]],

       [[nan, nan, nan],
        [nan, nan, nan],
        [nan, nan, nan]]])
Sign up to request clarification or add additional context in comments.

2 Comments

The first method doesn't work but the second method does work. Any thoughts why the first doesn't work? I know the nan is not a proper bool mask but thats how my data arrives.
It works on my system with numpy 1.19.2. Maybe explicitly use switch==True instead of switchhelps.
1

This would be much easier if you used a proper boolean mask. Numpy allows for boolean indexing, but placing an nan in the array turns it into a float.

For this particular example, it doesn't matter which value NaNs take, so you can do

switch = switch.astype(bool)
result = np.full_like(a, np.nan)
result[switch] = a[switch]

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.