Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在三个阵列中查找最近的三个x,y点_Python_Numpy - Fatal编程技术网

Python 在三个阵列中查找最近的三个x,y点

Python 在三个阵列中查找最近的三个x,y点,python,numpy,Python,Numpy,在Python中,我有三个包含x和y坐标的列表。每个列表包含128个点。如何有效地找到最近的三个点 这是我的python代码,但效率不够: def findclosest(c1, c2, c3): mina = 999999999 for i in c1: for j in c2: for k in c3: # calculate sum of distances between po

在Python中,我有三个包含x和y坐标的列表。每个列表包含128个点。如何有效地找到最近的三个点

这是我的python代码,但效率不够:

   def findclosest(c1, c2, c3):
       mina = 999999999
       for i in c1:
          for j in c2:
             for 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
def findclosest(c1、c2、c3):
mina=99999999
对于c1中的i:
对于c2中的j:
对于c3中的k:
#计算点之间距离的总和
d=xy3dist(i,j,k)
如果d

您知道如何使用numpy实现这一点吗?

您可以使用numpy的广播功能对两个内部循环进行矢量化:


import numpy as np

def findclosest(c1, c2, c3):
   c1 = np.asarray(c1)
   c2 = np.asarray(c2)
   c3 = np.asarray(c3)

   for arr in (c1, c2, c3):
       if not (arr.ndim == 2 and arr.shape[1] == 2):
           raise ValueError("expected arrays of 2D coordinates")

   min_val = np.inf
   min_pos = None

   for a, i 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])

将numpy作为np导入
def findclosest(c1、c2、c3):
c1=np.asarray(c1)
c2=np.asarray(c2)
c3=np.asarray(c3)
对于arr in(c1、c2、c3):
如果不是(arr.ndim==2和arr.shape[1]==2):
raise VALUERROR(“预期的二维坐标数组”)
最小值=np.inf
最小位置=无
对于a,i在枚举(c1)中:
d=xy3dist(i,c2.T[:,:,np.newaxis],c3.T[:,np.newaxis,:)
k=np.argmin(d)
如果d.平坦[k]<最小值:
最小值=d.平[k]
b、 c=np.解列指数(k,d.形)
最小位置=(a、b、c)
打印a,min_val,d.min()
返回最小值,最小位置
def XY3列表(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)
返回l1+l2+l3
np.random.seed(1234)
c1=np.rand.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
打印值,xy3dist(c1[a]、c2[b]、c3[c])
也可以对所有3个循环进行矢量化

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)
最小值=d.平[k]
a、 b,c=np.解列指数(k,d.形)
最小位置=(a、b、c)
返回最小值,最小位置

如果数组非常大,
findclosest
可能比
findclosest2
更好,因为它使用的内存更少。(如果数组很大,则只对最里面的一个循环进行矢量化。)


您可以在谷歌上搜索“numpy广播”以了解更多np.newaxis的功能

您可以使用numpy的广播功能对两个内部循环进行矢量化:


import numpy as np

def findclosest(c1, c2, c3):
   c1 = np.asarray(c1)
   c2 = np.asarray(c2)
   c3 = np.asarray(c3)

   for arr in (c1, c2, c3):
       if not (arr.ndim == 2 and arr.shape[1] == 2):
           raise ValueError("expected arrays of 2D coordinates")

   min_val = np.inf
   min_pos = None

   for a, i 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])

将numpy作为np导入
def findclosest(c1、c2、c3):
c1=np.asarray(c1)
c2=np.asarray(c2)
c3=np.asarray(c3)
对于arr in(c1、c2、c3):
如果不是(arr.ndim==2和arr.shape[1]==2):
raise VALUERROR(“预期的二维坐标数组”)
最小值=np.inf
最小位置=无
对于a,i在枚举(c1)中:
d=xy3dist(i,c2.T[:,:,np.newaxis],c3.T[:,np.newaxis,:)
k=np.argmin(d)
如果d.平坦[k]<最小值:
最小值=d.平[k]
b、 c=np.解列指数(k,d.形)
最小位置=(a、b、c)
打印a,min_val,d.min()
返回最小值,最小位置
def XY3列表(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)
返回l1+l2+l3
np.random.seed(1234)
c1=np.rand.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
打印值,xy3dist(c1[a]、c2[b]、c3[c])
也可以对所有3个循环进行矢量化

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)
最小值=d.平[k]
a、 b,c=np.解列指数(k,d.形)
最小位置=(a、b、c)
返回最小值,最小位置

如果数组非常大,
findclosest
可能比
findclosest2
更好,因为它使用的内存更少。(如果数组很大,则只对最里面的一个循环进行矢量化。)


你可以在谷歌上搜索“numpy广播”,了解更多np.newaxis的功能

让我们尝试一些不同的解决方案

我将使用numpy的随机函数初始化三个数组。如果现有变量是元组列表或列表列表,只需对它们调用
np.array

import numpy as np

c1 = np.random.normal(size=(128, 2))
c2 = np.random.normal(size=(128, 2))
c3 = np.random.normal(size=(128, 2))

首先,让我们对代码计时,这样我们就有了一个起点

def findclosest(c1, c2, c3):
    mina = 999999999
    for i in c1:
        for j in c2:
            for k in c3:
                 # calculate sum of distances between points
                 d = xy3dist(i,j,k)
                 if d < mina:
                     mina = d
    return mina

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

%timeit findclosest(c1, c2, c3)
# 1 loops, best of 3: 23.3 s per loop
因此,使用
cdist
可以给我们带来一个数量级的加速


然而,这甚至不能与@pv的答案相比。his的一个实现,去掉了一些东西,以便与以前的解决方案进行更好的比较(关于返回点的实现,请参见@pv的答案)


因此,这是一个巨大的加速,绝对是正确的答案。

让我们尝试选择一些不同的解决方案

我将使用numpy的随机函数初始化三个数组。如果现有变量是元组列表或列表列表,只需对它们调用
np.array

import numpy as np

c1 = np.random.normal(size=(128, 2))
c2 = np.random.normal(size=(128, 2))
c3 = np.random.normal(size=(128, 2))

首先,让我们对代码计时,这样我们就有了一个起点

def findclosest(c1, c2, c3):
    mina = 999999999
    for i in c1:
        for j in c2:
            for k in c3:
                 # calculate sum of distances between points
                 d = xy3dist(i,j,k)
                 if d < mina:
                     mina = d
    return mina

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

%timeit findclosest(c1, c2, c3)
# 1 loops, best of 3: 23.3 s per loop
因此,使用
cdist
可以给我们带来一个数量级的加速


然而,这甚至不能与@pv的答案相比。his的一个实现,去掉了一些东西,以便与以前的解决方案进行更好的比较(关于返回点的实现,请参见@pv的答案)


因此,这是一个巨大的加速,绝对是正确的答案。

距离函数xy3dist是什么?抱歉-帖子更新。它可以简化