การกรองพิกัดตามระยะทางจากจุดหนึ่ง

ฉันมีสองอาร์เรย์พูดว่า:

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])

ฉันต้องการค้นหาค่าทั้งหมดของ A ซึ่งไม่อยู่ในรัศมี 2 จาก B

คำตอบของฉันควรเป็น:

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

มีวิธี pythonic ในการทำเช่นนี้หรือไม่?

สิ่งที่ฉันได้ลองคือ:

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

แต่ฉันรู้ว่า np.extract แบน A และฉันไม่ได้รับสิ่งที่ฉันคาดหวัง


person user3185171    schedule 11.12.2017    source แหล่งที่มา


คำตอบ (2)


ให้ R เป็นรัศมีตรงนี้ เราจะมีวิธีแก้ไขไม่กี่วิธีดังที่กล่าวไว้ต่อไป

แนวทาง #1 : การใช้ cdist -

from scipy.spatial.distance import cdist

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

แนวทาง #2 : การใช้ np.einsum -

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

แนวทาง #3 : การใช้ np.linalg.norm -

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

แนวทาง #4 : การใช้ matrix-multiplication กับ 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 เพียงแทนที่ > ด้วย < ในวิธีแก้ปัญหาที่กล่าวมาข้างต้น

person Divakar    schedule 11.12.2017

อีกวิธีที่มีประโยชน์ที่ไม่ได้กล่าวถึงโดย @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

person jakevdp    schedule 12.12.2017