deleting certain entries in numpy array

Ben Finney ben+python at benfinney.id.au
Wed Jul 1 22:16:43 CEST 2009


Sebastian Schabe <sebastian.schabe at gmx.de> writes:

> I want to avoid a for loop (if possible!!!) cause I think (but don't
> know) numpy array are handled in another way.

Yes, Numpy arrays can be indexed logically by a boolean array.

> I think numpy.delete is the right function for discarding the values,
> but I don't know how to build the indices.

You don't need to discard the values. You can get a new array which is a
filtered version of an existing array, by using an array of bool values
as the index to the old array::

    >>> import numpy
    >>> mask = numpy.array([
    ...     [  0,   0,   0,   0,   0,   0,   0,   0,   0],
    ...     [  0,   0,   0,   0,   0,   0,   0,   0,   0],
    ...     [  0,   0,   0,   0,   0,   0,   0,   0,   0],
    ...     [  0,   0,   0,   0,   0,   0,   0,   0,   0],
    ...     [  0,   0,   0,   0,   0,   0,   0,   0,   0],
    ...     [  0,   0, 255, 255, 255,   0,   0, 255,   0],
    ...     [  0,   0, 255, 255, 255,   0,   0, 255,   0],
    ...     [  0,   0,   0,   0,   0,   0,   0,   0,   0],
    ...     [  0,   0,   0,   0,   0,   0,   0,   0,   0],
    ...     [  0,   0,   0,   0,   0,   0,   0,   0,   0],
    ...     ], dtype=numpy.uint8)
    >>> mask > 0
    array([[False, False, False, False, False, False, False, False, False],
           [False, False, False, False, False, False, False, False, False],
           [False, False, False, False, False, False, False, False, False],
           [False, False, False, False, False, False, False, False, False],
           [False, False, False, False, False, False, False, False, False],
           [False, False,  True,  True,  True, False, False,  True, False],
           [False, False,  True,  True,  True, False, False,  True, False],
           [False, False, False, False, False, False, False, False, False],
           [False, False, False, False, False, False, False, False, False],
           [False, False, False, False, False, False, False, False, False]],
           dtype=bool)
    >>> mask[mask > 0]
    array([255, 255, 255, 255, 255, 255, 255, 255], dtype=uint8)

However, your case is somewhat more tricky: you need to construct the
boolean array based on coordinates from a separate array. That doesn't
require a for loop statement, but AFAICT it does require manually
generating the array of bools. I've done it with a list comprehension::

    >>> pos = numpy.array([
    ...     [  3.,   2.,   0.,   0.],
    ...     [  3.,   4.,   0.,   0.],
    ...     [  5.,   2.,   0.,   0.],
    ...     [  5.,   4.,   0.,   0.],
    ...     [  6.,   2.,   0.,   0.],
    ...     [  6.,   7.,   0.,   0.],
    ...     [  0.,   0.,   0.,   0.],
    ...     [  8.,   8.,   0.,   0.],
    ...     ])
    >>> pos[numpy.array(
    ...     [mask[int(x), int(y)] > 0 for (x, y) in pos[:, 0:2]])]
    array([[ 5.,  2.,  0.,  0.],
           [ 5.,  4.,  0.,  0.],
           [ 6.,  2.,  0.,  0.],
           [ 6.,  7.,  0.,  0.]])

Here it is again, showing my working steps::

    >>> pos[:, 0:2]
    array([[ 3.,  2.],
           [ 3.,  4.],
           [ 5.,  2.],
           [ 5.,  4.],
           [ 6.,  2.],
           [ 6.,  7.],
           [ 0.,  0.],
           [ 8.,  8.]])
    >>> [(int(x), int(y)) for (x, y) in pos[:, 0:2]]
    [(3, 2), (3, 4), (5, 2), (5, 4), (6, 2), (6, 7), (0, 0), (8, 8)]
    >>> [mask[int(x), int(y)] for (x, y) in pos[:, 0:2]]
    [0, 0, 255, 255, 255, 255, 0, 0]
    >>> [mask[int(x), int(y)] > 0 for (x, y) in pos[:, 0:2]]
    [False, False, True, True, True, True, False, False]
    >>> numpy.array(
    ...     [mask[int(x), int(y)] > 0 for (x, y) in pos[:, 0:2]])
    array([False, False,  True,  True,  True,  True, False, False],
    dtype=bool)
    >>> pos[numpy.array(
    ...     [mask[int(x), int(y)] > 0 for (x, y) in pos[:, 0:2]])]
    array([[ 5.,  2.,  0.,  0.],
           [ 5.,  4.,  0.,  0.],
           [ 6.,  2.,  0.,  0.],
           [ 6.,  7.,  0.,  0.]])

-- 
 \                            “Holy knit one purl two, Batman!” —Robin |
  `\                                                                   |
_o__)                                                                  |
Ben Finney



More information about the Python-list mailing list