0

Given a sample numpy array like so:

a = np.array([[[[0,0,0], [0,0,0], [0,0,0]],
               [[0,0,0], [0,0,0], [0,0,0]]],
              [[[0,1,2], [1,1,1], [1,1,1]],
               [[1,1,1], [1,2,2], [1,1,1]]],
              [[[0,1,2], [1,1,1], [1,1,1]],
               [[1,1,1], [1,2,2], [1,1,1]]],
              [[[0,1,2], [1,1,1], [1,1,1]],
               [[1,1,1], [1,2,2], [1,1,1]]]])
#a.shape = (4, 2, 3, 3)

How can I get it to return a numpy array with shape (3,2,3,3) considering that the first element is all zeros? My dataset is a bigger one of shape (m, x, y, z) and I'll need to return non-zero (m-n, x,y,z) arrays where n are the (x,y,z) shaped arrays with all zeros.

So far I tried this:

mask = np.equal(a, np.zeros(shape=(2,3,3)))

'''
Returns:
        [[[[ True  True  True]
   [ True  True  True]
   [ True  True  True]]

  [[ True  True  True]
   [ True  True  True]
   [ True  True  True]]]


 [[[ True False False]
   [False False False]
   [False False False]]

  [[False False False]
   [False False False]
   [False False False]]]


 [[[ True False False]
   [False False False]
   [False False False]]

  [[False False False]
   [False False False]
   [False False False]]]


 [[[ True False False]
   [False False False]
   [False False False]]

  [[False False False]
   [False False False]
   [False False False]]]]
'''

But applying a[~mask] gives me a flattened array:

[1 2 1 1 1 1 1 1 1 1 1 1 2 2 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 2 1 1 1 1 2 1
 1 1 1 1 1 1 1 1 1 2 2 1 1 1] (51,)

What I need is something like this:

np.array([[[[0,1,2], [1,1,1], [1,1,1]],
           [[1,1,1], [1,2,2], [1,1,1]]],
          [[[0,1,2], [1,1,1], [1,1,1]],
           [[1,1,1], [1,2,2], [1,1,1]]],
          [[[0,1,2], [1,1,1], [1,1,1]],
           [[1,1,1], [1,2,2], [1,1,1]]]])

Bonus: I need to apply this to a separate/mirror (m, x, y, z) shaped array so maybe I'll need a masked approach?

1
  • 1
    Well a problem is that if there are for instance two sublists where we remove only for one sublist an element, then the two sublists no longer contain the same number of elements, which is a requirement in numpy. Commented Feb 13, 2018 at 22:24

1 Answer 1

2

Use all over axises other than the first axis to create the boolean array for indexing:

a[~(a == 0).all(axis=(1,2,3))]

#array([[[[0, 1, 2],
#         [1, 1, 1],
#         [1, 1, 1]],

#        [[1, 1, 1],
#         [1, 2, 2],
#         [1, 1, 1]]],


#       [[[0, 1, 2],
#         [1, 1, 1],
#         [1, 1, 1]],

#        [[1, 1, 1],
#         [1, 2, 2],
#         [1, 1, 1]]],


#       [[[0, 1, 2],
#         [1, 1, 1],
#         [1, 1, 1]],

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

2 Comments

Ah great, this does what I want! But I also need to generate a mask for applying it to another separate array of the same dimension (see updated question).
Nevermind, found out I can use mask = (a == 0).all(axis=(1,2,3)). Marking answer as accepted!

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.