Python 在2个单独的numpy数组中查找匹配点

Python 在2个单独的numpy数组中查找匹配点,python,arrays,performance,numpy,compare,Python,Arrays,Performance,Numpy,Compare,我有两个不同大小的数组,其中包含3d点。我希望有效地比较这两个数组,找到匹配的点,并最终返回简单数量的匹配点 pA=[[0,0,0],[0,1,0],[1,2,4],[10,3,4],[1,20,1],[5,3,2]] pB=[[14,1,0],[1,2,4],[1,20,1],[15,1,0]] #returns 2 目前,我有一个草率的循环来实现这一点,但它对性能不是很友好,这是一个问题,因为我正在尝试匹配多对具有更多点数的数组 t= np.array([pA[x]==pB for x

我有两个不同大小的数组,其中包含3d点。我希望有效地比较这两个数组,找到匹配的点,并最终返回简单数量的匹配点

pA=[[0,0,0],[0,1,0],[1,2,4],[10,3,4],[1,20,1],[5,3,2]]
pB=[[14,1,0],[1,2,4],[1,20,1],[15,1,0]]

#returns 2
目前,我有一个草率的循环来实现这一点,但它对性能不是很友好,这是一个问题,因为我正在尝试匹配多对具有更多点数的数组

t= np.array([pA[x]==pB for x in range(len(pA))]).sum(2)
print np.sum(t==3)
我只是不知道如何有效地比较两个不同大小的多维数组。然后,如何对大量对进行多次迭代

编辑

找到了一个快速组合阵列的解决方案,创建了一个独特的阵列版本,然后比较了两个阵列的长度

pts=np.concatenate((pA,pB),axis=0)
pts2 = np.unique(pts.view([('', pts.dtype)]*pts.shape[1]))
return len(pts)-len(pts2)

不知道如何在完整数据集上执行此操作,但请尝试使用Scipy的kdtree:

from scipy.spatial import cKDTree

pA=[[0,0,0],[0,1,0],[1,2,4],[10,3,4],[1,20,1],[5,3,2]]
pB=[[14,1,0],[1,2,4],[1,20,1],[15,1,0]]

kdtree = cKDTree(pA)
dists, inds = kdtree.query(pB, distance_upper_bound=1e-5)
result = (dists == 0).sum()

    • 这里有一种方法,只需使用
      numpy
      操作。这里的基本思想是将这两个列表连接到一个numpy数组中。然后,我们按行排序,在连续的行中引入匹配点。接下来,我们执行
      diff
      以获得匹配行的所有零行,这由
      np.all(…==0,1)
      拾取。我们对所有这些事件进行计数,以获得这两个列表之间匹配点计数的期望输出

      实现如下所示-

      import numpy as np
      
      # Inputs
      pA=[[0,0,0],[0,1,0],[1,2,4],[10,3,4],[1,20,1],[5,3,2]]
      pB=[[14,1,0],[1,2,4],[1,20,1],[15,1,0]]
      
      # Form concatenate array of pA and pB
      pts = np.concatenate((pA,pB),axis=0)
      
      # Sort pts by rows
      spts = pts[pts[:,1].argsort(),]
      
      # Finally get counts by DIFFing along rows and counting all zero rows
      counts = np.sum(np.diff(np.all(np.diff(spts,axis=0)==0,1)+0)==1)
      
      输出-

      In [152]: counts
      Out[152]: 2
      
      即使两个列表中都有重复的点,上述代码仍然有效。因此,让我们在前面代码的输入中添加一些重复点-

      # Inputs
      pA=[[0,0,0],[0,1,0],[1,2,4],[10,3,4],[1,20,1],[5,3,2],[1,2,4]]
      pB=[[14,1,0],[1,2,4],[1,20,1],[15,1,0],[1,2,4]]
      
      使用修改后的输入运行代码后,输出仍然保持为
      2
      ,这是预期的输出

      如果确定两个列表中都没有重复条目,则可以使用简化版本替换最后一步-

      counts = np.sum(np.all(np.diff(spts,axis=0)==0,1))
      

      Scipy显然有一些工具可以很好地解决这个问题。唯一的问题是,这适用于要在Autodesk Maya中运行的脚本,我需要为此特定Maya版本编译Scipy模块(我在这方面没有经验)。如果必要的话可能不会太难。我明白了。numpy是否与Maya一起使用?numpy我能够找到Maya的编译版本。在我短暂的搜索中,我找不到一个简单的。不过,我可能需要花更多的精力让Scipy在Maya中工作,因为从我所知不多的情况来看,它似乎有一些更好的3D功能。您可能会幸运地使用像这样的纯Python实现:。或许还有另一种简单有效的方法。不过,值得一提的是您的Maya约束。当涉及到
      numpy
      时,kdtree似乎非常有用。很高兴知道这件事!每个列表中是否有重复的点?这个想法基本上就是我目前使用的,尽管我相信你的想法要优雅得多。我的变体连接数组,然后创建一个新数组,删除所有重复项,并比较两个数组长度以获得数字
      pts=np.concatenate((pA,pB),axis=0)pts2=np.unique(pts.view([('',pts.dtype)]*pts.shape[1])counts=len(pts)-len(pts2)
      @AlexRideout是的,在原始版本中,
      all+diff
      部分本质上是
      唯一的
      查找,可能是有效的,因为它还避免了中间变量的创建。在对解决方案的新编辑结束时为没有重复条目的列表添加了简化版本。好奇的是,您是否有机会测试这些方法的运行时性能?您的方法显然比我的
      unique
      方法更优雅。到目前为止,我还没有机会进行任何官方测量。大多数人只对Maya场景中的几何体进行了主观测试。目前,我正在使用一个循环来迭代我生成的所有点阵列对(可能是向量化这一步的某种方式?),这大约每秒运行6000对,这对我的实现来说是可以接受的。虽然我已经处理了超过200000双,所以不是很理想。