Coordinate filtering based on distance from a point

I have two arrays:

A = np.array([[ 1.  ,  1.  ,  0.5 ],
              [ 2.  ,  2.  ,  0.7 ],
              [ 3.  ,  4.  ,  1.2 ],
              [ 4.  ,  3.  ,  2.33],
              [ 1.  ,  2.  ,  0.5 ],
              [ 6.  ,  5.  ,  0.3 ],
              [ 4.  ,  5.  ,  1.2 ],
              [ 5.  ,  5.  ,  1.5 ]])

B = np.array([2,1])

I would like to find all values Athat are not within a radius of 2 from B.

My answer should be:

C = [[3,4,1.2],[4,3,2.33],[6,5,0.3],[4,5,1.2],[5,5,1.5]]

Is there a pythonic way to do this?

I tried:

radius = 2
C.append(np.extract((cdist(A[:, :2], B[np.newaxis]) > radius), A))

But I realized that np.extractflattens A, and I do not get the expected.

+3
source share
2 answers

Let be the Rradius. We would have several methods to solve it, as described below.

Approach No. 1: Use cdist-

from scipy.spatial.distance import cdist

A[(cdist(A[:,:2],B[None]) > R).ravel()]

Approach # 2: Use np.einsum-

d = A[:,:2] - B
out = A[np.einsum('ij,ij->i', d,d) > R**2]

Approach No. 3: Use np.linalg.norm-

A[np.linalg.norm(A[:,:2] - B, axis=1) > R]

Approach No. 4: Use matrix-multiplicationwith np.dot-

A[(A[:,:2]**2).sum(1) + (B**2).sum() - 2*A[:,:2].dot(B) > R**2]

№ 5: einsum matrix-multiplication -

A[np.einsum('ij,ij->i',A[:,:2],A[:,:2]) + B.dot(B) - 2*A[:,:2].dot(B) > R**2]

# 6: broadcasting -

A[((A[:,:2] - B)**2).sum(1) > R**2]

, R, > < .

+3

, @Divakar, cKDTree:

from scipy.spatial import cKDTree

# Find indices of points within radius
radius = 2
indices = cKDTree(A[:, :2]).query_ball_point(B, radius)

# Construct a mask over these points
mask = np.zeros(len(A), dtype=bool)
mask[indices] = True

# Extract values not among the nearest neighbors
A[~mask]

, , , A.

+2

Source: https://habr.com/ru/post/1690629/


All Articles