Reputation: 23068
The array x
denotes a bounding box, delimited by two (x,y) coordinates:
x = np.array([[2, 1], [5, 3]])
And the array p
denotes a collection of points by their (x,y) coordinates:
p = np.array([[3, 2], [6, 4], [3, 4], [4, 2]])
For each point in p
, I want to determine (in one operation) whether it's in the bounding-box x
, so as to get the following result.
result = np.array([1, 0, 0, 1])
I've though about np.where()
but not sure how to process the whole collection of points in one operation. Also, wouldn't a purely numerical approach be faster?
EDIT:
I'd be interested as well in the case where multiple bounding boxes are present, such as:
# [[bbox_1], [bbox_2], [bbox_2]]
# with each bbox as [x1 y1 x2 y2]
x = np.array([[2, 1, 5, 3], [2, 2, 4, 6], [0, 4, 3, 2]])
with the result being of the form
# [p1_bbox_1, p2_bbox_1, p3_bbox_1, p4_bbox_1], [p1_bbox_2, p2_bbox_2 ...]]
# results not necessarily exact but shape is correct
result = np.array([[True, False, False, True], [True, False, False, False], [False, False, True, False]])
A point sitting exactly on a bbox boundary should be considered inside.
Upvotes: 1
Views: 2151
Reputation: 221574
With slicing and leveraging broadcasting
-
In [24]: ((p>=x[0]) & (p<=x[1])).all(1)
Out[24]: array([ True, False, False, True])
This assumes bounding box array as :
[[x1,y1]
[x2,y2]]
If the format is say [x1,y1,x2,y2]
(1D array) that define the box corners, we could get it like so -
((p>=x[:2]) & (p<=x[2:])).all(1)
Also, edit >=
to >
and so on for exclusiveness on boundaries.
Extend to multiple boxes
For multiple boxes in x
with a format of 2D array :
[[B1x1,B1y1,B1x2,B1y2],
[B2x1,B2y1,B2x2,B2y2], ..
]
So, B1 is box-1
, B2
is box-2
and so on, while (x1,y1)
and (x2,y2)
are the bounding box corners for each box. The solution would be -
((p>=x[:,None,:2]) & (p<=x[:,None,2:])).all(2)
Upvotes: 2