我正在尝试计算两个元组列表的欧几里德距离,阈值为4。如果阈值小于特定值,则递增计数器。每个元组是该点的x,y,z坐标。无论如何,我可以降低list1与list2的比较..
X = [ (1,2,3),(2,3,4), (4,5,6) ]
Y = [ (1,2,2) , (3,4,5),(6,7,8) ]
from math import sqrt
dist_X = [ sqrt((p[0] - 0)**2 + (p[1] - 0)**2 + (p[2] - 0)**2) for p in X]
dist_Y = [ sqrt((p[0] - 0)**2 + (p[1] - 0)**2 + (p[2] - 0)**2) for p in Y]
for x in dist_X:
print (x , [ i for i,y in enumerate(dist_Y) if abs(x-y) <= 4])
我在考虑首先使用原点(0,0,0)计算每个点的欧几里德距离,这样两个列表现在都包含彼此接近的点,但由于它的标量值不起作用。我正朝着正确的方向前进吗?
修改
visited1 = [ (1,2,3),(2,3,4), (4,5,6) ]
visited2 = [ (1,2,2) , (3,4,5),(6,7,8) ]
def euclidean(a,b):
return sqrt((a[0] - b[0])**2+(a[1]-b[1])**2+(a[2]-b[2])**2)
comparison = 0
for i,j in enumerate(visited2):
for k,l in enumerate(visited1):
if euclidean(visited2[i],visited1[k]) < 4:
count += 1
comparison += 1
在这里,list1的每个元素都与list2中的每个元素进行比较。我想知道是否有一种方法可以最小化给定点(x,y,z)的比较?
答案 0 :(得分:3)
有时加速的一个预计算是kd-trees。我对蛮力进行了快速测试,发现对于较大的列表,它们可以快得多:
# n = 10
# trees 0.08512560 ms
# brute 0.01425540 ms
# n = 100
# trees 0.20338160 ms
# brute 0.09876890 ms
# n = 1000
# trees 6.40193820 ms
# brute 16.15429670 ms
# n = 10000
# trees 298.69653380 ms
# brute 1393.71134270 ms
代码:
import numpy as np
from scipy.spatial import cKDTree
import types
from timeit import timeit
def setup_data(n, k):
data = {'d1': np.random.randint(0, 10, (n, 3)),
'd2': np.random.randint(0, 10, (n, 3)),
'mx': k}
return data
def f_trees(d1, d2, mx):
t1 = cKDTree(d1)
t2 = cKDTree(d2)
return t1.count_neighbors(t2, mx)
def f_brute(d1, d2, mx):
dist2 = np.add.outer(np.einsum('ij,ij->i', d1, d1), np.einsum('ij,ij->i', d2, d2)) - 2*np.einsum('ij, kj', d1, d2)
return np.count_nonzero(dist2 <= mx*mx)
for n in (10, 100, 1000, 10000):
data = setup_data(n, 4)
ref = np.array(f_trees(**data))
print(f'n = {n}')
for name, func in list(globals().items()):
if not name.startswith('f_') or not isinstance(func, types.FunctionType):
continue
try:
assert np.allclose(ref, func(**data))
print("{:16s}{:16.8f} ms".format(name[2:], timeit(
'f(**data)', globals={'f':func, 'data':data}, number=10)*100))
except:
print("{:16s} apparently failed".format(name[2:]))
答案 1 :(得分:0)
在2D中绘制它以查看它的外观。与原点距离大致相同的点不必然彼此接近 - 在那里你有三角不等式。例如,比较点(0,10),(0,11)和(-8,-6)。他们来自原点的所有10-11个单位,但最后一个远不及其他两个单位。
如果你想知道两个点是否彼此接近,你需要计算这两个点之间的距离,而不是到任意第三点的距离。这个问题的复杂性是二次的,而不是线性的。