Reputation: 175
I have the following ndarray:
[[ 3 271]
[ 4 271]
[375 271]
[ 3 216]
[375 216]
[ 0 0]
[ 0 546]
[378 546]
[378 0]
[ 1 182]
[ 2 181]
[376 181]
[377 182]
[377 544]
[376 545]]
Essentially a bunch of X,Y coordinates/points. I'd like to be able to select X,Y coordinates "near" a given point on both axes.
For example, given a target point of [3, 271], I'd first retrieve all other points at this Y location (271), to then be able to select rows -/+ 3 on the X axis. For the above, that should yield:
[ 3 271]
[ 4 271]
I've gotten as far as getting all rows with the same Y value like this:
index_on_y = points[:,1] == point[1]
shared_y = points[index_on_y]
This returns:
shared_y:
[[ 3 271]
[ 4 271]
[375 271]]
How do I now select all rows from this array where the X value (column 0) can be anything between 0-6? I've tried various combinations of slicing/indexing/np.where but I've not been able to get the desired result. The below is as far as I got, but I know it is incorrect; just don't know what the right (and most efficient) way of doing it would be:
def nearby_contour_points_x(self, point, points, radius):
index_on_y = points[:,1] == point[1] # correct
shared_y = points[index_on_y] # correct
x_vals = shared_y[:,0] # not good?
index_on_x = np.where(np.logical_or(x_vals <= (point[0] - radius), x_vals <= (point[0] + radius)))
return shared_y[index_on_x]
Ideally, I wouldn't have to first group on one of the axes.
Upvotes: 0
Views: 96
Reputation: 23743
With a
as the array in your example.
target = np.array([3, 271])
Subtract the target
diff = a - target
y (column one) must be the same as the target - this results in a boolean array of shape a.shape[0]:
y_rows = diff[:,1] == 0
x is within a range of the target - this results in a boolean array of shape a.shape[0]:
x_rows = np.logical_and(diff[:,0] <= 6, diff[:,0] >= 0)
Make a mask for boolean indexing - its shape will be (15,) - a.shape[0], allowing it to broadcast along the rows
mask = np.logical_and(x_rows, y_rows)
>>> a[mask]
array([[ 3, 271],
[ 4, 271]])
Foregoing the initial subtraction and a little more generalized:
x_rows = np.logical_and(a[:,0] >= target[0] - 3, a[:,0] <= target[0] + 3)
y_rows = a[:,1] == target[1]
mask = np.logical_and(x_rows, y_rows)
Upvotes: 1
Reputation: 3706
perhaps an abuse of isclose
but works
ys = np.array([[ 3, 271],
[ 4, 271],
[375, 271]])
np.compress(np.all(np.isclose(ys, [3,271], rtol=0, atol=3), axis=1), ys, axis=0)
Out[273]:
array([[ 3, 271],
[ 4, 271]])
Upvotes: 0