在3d数组中找到2d元素,这些元素类似于另一个3d数组中的2d元素

时间:2016-01-28 09:14:03

标签: python arrays numpy

我有两个3D数组,想要在一个数组中识别2D元素,在另一个数组中有一个或多个类似的对应物。

这适用于Python 3:

{{1}}

但当然这种方法非常慢。请告诉我,有一种更有效的方式(以及它是什么)。 THX。

2 个答案:

答案 0 :(得分:1)

您正在尝试执行所有最近邻居类型的查询。这是具有特殊O(n log n)算法的东西,我不知道python实现。但是你可以使用常规的最近邻居,它也是O(n log n)稍慢一点。例如scipy.spatial.KDTreecKDTree

import numpy as np
import random
np.random.seed(123)
A = np.round(np.random.rand(25000,2,2),2)
B = np.round(np.random.rand(25000,2,2),2)

import scipy.spatial
tree = scipy.spatial.cKDTree(A.reshape(25000, 4))
results = tree.query_ball_point(B.reshape(25000, 4), r=1e-04, p=1)

print [r for r in results if r != []]
# [[14252], [1972], [7108], [13369], [23171]]

query_ball_point()allclose()并不完全等效,但足够接近,特别是如果您不关心rtol参数allclose()。您还可以选择指标(城市街区p=1或欧几里德p=2)。

P.S。考虑将query_ball_tree()用于非常大的数据集。在这种情况下,A和B都必须编入索引。

P.S。我不确定元素的二维性应该具有什么影响;我给出的示例代码将它们视为1d,并且至少在使用城市街区指标时是相同的。

答案 1 :(得分:0)

np.allclose的文档中,我们有:

  

如果以下等式是元素为True,那么allclose返回   真。

     

绝对(a - b)< =(atol + rtol * absolute(b))

使用该标准,我们可以使用broadcasting进行矢量化实现,为所述问题进行自定义,如此 -

# Setup parameters
rtol,atol = 1e-04, 1e-06

# Use np.allclose criteria to detect true/false across all pairwise elements
mask = np.abs(A[:,None,] - B) <= (atol + rtol * np.abs(B))

# Use the problem context to get final output
out = np.nonzero(mask.all(axis=(2,3)).any(1))[0]