5

I am trying to all rows that only contain zeros from a NumPy array. For example, I want to remove [0,0] from

n = np.array([[1,2], [0,0], [5,6]])

and be left with:

np.array([[1,2], [5,6]])
3
  • 5
    you want to remove a row based on its value or its index? Commented Apr 12, 2012 at 8:40
  • 1
    @user1220022: What kind of values do you want to test? any sequence? or only know whether there are only zeroes in the row? Commented Apr 12, 2012 at 9:02
  • whether there are only zeros in the row Commented Apr 12, 2012 at 10:33

4 Answers 4

10

To remove the second row from a numpy table:

import numpy
n = numpy.array([[1,2],[0,0],[5,6]])
new_n = numpy.delete(n, 1, axis=0)

To remove rows containing only 0:

import numpy
n = numpy.array([[1,2],[0,0],[5,6]])
idxs = numpy.any(n != 0, axis=1) # index of rows with at least one non zero value
n_non_zero = n[idxs, :] # selection of the wanted rows
Sign up to request clarification or add additional context in comments.

2 Comments

numpy.delete(n, numpy.s_[1], axis=0) can be simplified as numpy.delete(n, 1). Furthermore, numpy.any(n != 0, axis=1) can be simplified as n.any(axis=1). And n[idx,:] can simply be replaced by n[idx].
PS: Sorry, numpy.delete(n, numpy.s_[1], axis=0) does need an axis parameter: it can be simplified as numpy.delete(n, 1, axis=0).
4

If you want to delete any row that only contains zeros, the fastest way I can think of is:

n = numpy.array([[1,2], [0,0], [5,6]])

keep_row = n.any(axis=1)  # Index of rows with at least one non-zero value
n_non_zero = n[keep_row]  # Rows to keep, only

This runs much faster than Simon's answer, because n.any() stops checking the values of each row as soon as it encounters any non-zero value (in Simon's answer, all the elements of each row are compared to zero first, which results in unnecessary computations).


Here is a generalization of the answer, if you ever need to remove a rows that have a specific value (instead of removing only rows that only contain zeros):

n = numpy.array([[1,2], [0,0], [5,6]])

to_be_removed = [0, 0]  # Can be any row values: [5, 6], etc.
other_rows = (n != to_be_removed).any(axis=1)  # Rows that have at least one element that differs
n_other_rows = n[other_rows]  # New array with rows equal to to_be_removed removed.

Note that this solution is not fully optimized: even if the first element of to_be_removed does not match, the remaining row elements from n are compared to those of to_be_removed (as in Simon's answer).

I'd be curious to know if there is a simple efficient NumPy solution to the more general problem of deleting rows with a specific value.

Using cython loops might be a fast solution: for each row, element comparison could be stopped as soon as one element from the row differs from the corresponding element in to_be_removed.

Comments

3

You can use numpy.delete to remove specific rows or columns.

For example:

n = [[1,2], [0,0], [5,6]]

np.delete(n, 1, axis=0)

The output will be:

array([[1, 2],
       [5, 6]])

2 Comments

This deletes the second element right? I should of been more specific, I want to remove the element which is [0,0] and there will only be one of them.
This answer tries to delete by index, not what the OP asked.
2

To delete according to value,which is an Object.
To do like this:

>>> n
array([[1, 2],
       [0, 0],
       [5, 6]])
>>> bl=n==[0,0]
>>> bl
array([[False, False],
       [ True,  True],
       [False, False]], dtype=bool)
>>> bl=np.any(bl,axis=1)
>>> bl
array([False,  True, False], dtype=bool)
>>> ind=np.nonzero(bl)[0]
>>> ind
array([1])
>>> np.delete(n,ind,axis=0)
array([[1, 2],
       [5, 6]])

1 Comment

+1 good suggestion, worked for me. You can also use np.all() instead to get those elements that are an exact match and not just contain a 0 (that is only [0,0]).

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.