deleting certain entries in numpy array
Ben Finney
ben+python at benfinney.id.au
Wed Jul 1 16:16:43 EDT 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