5

I need to remove the last arrays from a 3D numpy cube. I have:

a = np.array(
[[[1,2,3],
 [4,5,6],
 [7,8,9]],

[[9,8,7],
 [6,5,4],
 [3,2,1]],

[[0,0,0],
 [0,0,0],
 [0,0,0]],

[[0,0,0],
 [0,0,0],
 [0,0,0]]])

How do I remove the arrays with zero sub-arrays like at the bottom side of the cube, using np.delete?

(I cannot simply remove all zero values, because there will be zeros in the data on the top side)

Matt Hall
  • 7,614
  • 1
  • 23
  • 36
Claire.gen
  • 47
  • 3

5 Answers5

4

For a 3D cube, you might check all against the last two axes

a = np.asarray(a)
a[~(a==0).all((2,1))]

array([[[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]],

       [[9, 8, 7],
        [6, 5, 4],
        [3, 2, 1]]])
rafaelc
  • 57,686
  • 15
  • 58
  • 82
  • 1
    If one is specifically looking for zeros, one could even do `a[a.any((2, 1))]`, since `0` is considered equivalent to `False`. Makes the code a bit less readable for a negligible speedup though. – Daniel F Oct 08 '19 at 06:08
2

If you know where they are already, the easiest thing to do is slice them off:

a[:-2]

Results in:

array([[[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]],

       [[9, 8, 7],
        [6, 5, 4],
        [3, 2, 1]]])
Matt Hall
  • 7,614
  • 1
  • 23
  • 36
2

Here's one way to remove trailing all zeros slices, as mentioned in the question that we want to keep the all zeros slices in the data on the top side -

a[:-(a==0).all((1,2))[::-1].argmin()]

Sample run -

In [80]: a
Out[80]: 
array([[[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]],

       [[9, 8, 7],
        [6, 5, 4],
        [3, 2, 1]],

       [[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]],

       [[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]]])

In [81]: a[:-(a==0).all((1,2))[::-1].argmin()]
Out[81]: 
array([[[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]],

       [[9, 8, 7],
        [6, 5, 4],
        [3, 2, 1]]])
Divakar
  • 218,885
  • 19
  • 262
  • 358
0

Hope this helps,

a_new=[] #Create a empty list
for item in a:
        if not (np.count_nonzero(item) == 0): #check if inner matrix is empty or not
            a_new.append(item) #appending to inner matrix to the list

a_new=np.array(a_new) #creating numpy matrix with removed zero elements

Output:

array([[[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]],

       [[9, 8, 7],
        [6, 5, 4],
        [3, 2, 1]]])
0

Use any and select :)

a=np.array([[[1,2,3],
 [4,5,6],
 [7,8,9]],

[[9,8,7],
 [6,5,4],
 [3,2,1]],

[[0,0,0],
 [0,0,0],
 [0,0,0]],

[[0,0,0],
 [0,0,0],
 [0,0,0]]])
a[a.any(axis=2).any(axis=1)]
Sebastian Wozny
  • 16,943
  • 7
  • 52
  • 69