python - Finding closest three x,y points in three arrays -
in python, have 3 lists containing x , y coordinates. each list contains 128 points. how can find the closest 3 points in efficient way?
this working python code isn't efficient enough:
def findclosest(c1, c2, c3): mina = 999999999 in c1: j in c2: k in c3: # calculate sum of distances between points d = xy3dist(i,j,k) if d < mina: mina = d def xy3dist(a, b, c): l1 = math.sqrt((a[0]-b[0]) ** 2 + (a[1]-b[1]) ** 2 ) l2 = math.sqrt((b[0]-c[0]) ** 2 + (b[1]-c[1]) ** 2 ) l3 = math.sqrt((a[0]-c[0]) ** 2 + (a[1]-c[1]) ** 2 ) return l1+l2+l3
any idea how can done using numpy?
you can use numpy's broadcasting features vectorize 2 inner loops:
import numpy np def findclosest(c1, c2, c3): c1 = np.asarray(c1) c2 = np.asarray(c2) c3 = np.asarray(c3) arr in (c1, c2, c3): if not (arr.ndim == 2 , arr.shape[1] == 2): raise valueerror("expected arrays of 2d coordinates") min_val = np.inf min_pos = none a, in enumerate(c1): d = xy3dist(i, c2.t[:,:,np.newaxis], c3.t[:,np.newaxis,:]) k = np.argmin(d) if d.flat[k] < min_val: min_val = d.flat[k] b, c = np.unravel_index(k, d.shape) min_pos = (a, b, c) print a, min_val, d.min() return min_val, min_pos def xy3dist(a, b, c): l1 = np.sqrt((a[0]-b[0]) ** 2 + (a[1]-b[1]) ** 2 ) l2 = np.sqrt((b[0]-c[0]) ** 2 + (b[1]-c[1]) ** 2 ) l3 = np.sqrt((a[0]-c[0]) ** 2 + (a[1]-c[1]) ** 2 ) return l1+l2+l3 np.random.seed(1234) c1 = np.random.rand(5, 2) c2 = np.random.rand(9, 2) c3 = np.random.rand(7, 2) val, pos = findclosest(c1, c2, c3) a, b, c = pos print val, xy3dist(c1[a], c2[b], c3[c])
it's possible vectorize of 3 loops def findclosest2(c1, c2, c3): c1 = np.asarray(c1) c2 = np.asarray(c2) c3 = np.asarray(c3) d = xy3dist(c1.t[:,:,np.newaxis,np.newaxis], c2.t[:,np.newaxis,:,np.newaxis], c3.t[:,np.newaxis,np.newaxis,:]) k = np.argmin(d) min_val = d.flat[k] a, b, c = np.unravel_index(k, d.shape) min_pos = (a, b, c) return min_val, min_pos
if arrays big, findclosest
may better findclosest2
uses less memory. (and if arrays huge, vectorize 1 innermost loop.)
you can google "numpy broadcasting" learn more np.newaxis does
Comments
Post a Comment