测量到最近一组点的距离-python
我试图测量每个点到最近点组的最短欧几里德距离。使用下面的方法,我在两个不同的时间点在测量到最近一组点的距离-python,python,pandas,spatial,kdtree,Python,Pandas,Spatial,Kdtree,我试图测量每个点到最近点组的最短欧几里德距离。使用下面的方法,我在两个不同的时间点在x,y中显示了6个独特的点。我在x\u-ref,y\u-ref中记录了一个单独的xy点,我在其中传递一个半径。所以对于这个半径外的每个点,我想找到到半径内任何点的最短距离。对于半径内的点,只需返回0 计算距离测量每个特定点与其余点之间的距离。我希望返回到半径内最近点的距离 import pandas as pd import numpy as np import matplotlib.pyplot as plt
x,y
中显示了6个独特的点。我在x\u-ref,y\u-ref
中记录了一个单独的xy点,我在其中传递一个半径。所以对于这个半径外的每个点,我想找到到半径内任何点的最短距离。对于半径内的点,只需返回0
计算距离
测量每个特定点与其余点之间的距离。我希望返回到半径内最近点的距离
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial.distance import pdist, squareform
df = pd.DataFrame({
'Time' : [1,1,1,1,1,1,2,2,2,2,2,2],
'Item' : ['A','B','C','D','E','F','A','B','C','D','E','F'],
'x' : [5,5,8,3,6,2,6,7,4,2,7,6],
'y' : [-2,0,-2,0,0,4,-1,2,-3,4,-4,2],
'x_ref' : [4,4,4,4,4,4,4,4,4,4,4,4],
'y_ref' : [-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2],
})
# Determine square distance
square_dist = (df['x_ref'] - df['x']) ** 2 + (df['y_ref'] - df['y']) ** 2
# Return df of items within radius
inside_radius = df[square_dist <= 3 ** 2].copy()
def calculate_distances(df):
id_distances = pd.DataFrame(
squareform(pdist(df[['x','y']].to_numpy())),
columns = df['Item'],
index = df['Item'],
)
return id_distances
df_distances = df.groupby(['Time']).apply(calculate_distances).reset_index()
这里有一种使用方法,当您打算进行许多距离和邻居搜索时,它非常有用
将numpy导入为np
作为pd进口熊猫
从scipy.spatial导入KDTree
半径范围内的定义(z,半径,闭合=假):
中心=z['x_-ref','y_-ref']].mean()#它们都应该是相同的
z=z['x','y']]
距离=半径*1.0001(如果闭合),否则半径
dist,idx=KDTree(z).query(
中心,k=无,距离(上限=距离)
如果关闭:
idx=[如果d>>df.assign(distance=df.groupby('Time',group\u keys=False),则i代表d,i在zip中(dist,idx)。应用(
…在半径范围内(距离,半径=3,闭合=真)
时间项x y x_参考y_参考距离
01A 5-23-20.000000
1 B 5 0 3-2 0.000000
21c8-23-23000000
31D303-2000000
4 1 E 6 0 3-2 1.000000
5 1 F 2 4 3-2 4.123106
62a 6-14-200.000000
72B724-23162278
82 C4-34-200.000000
92D2444-26403124
102E7-443.162278
11 2 F 6 2 4-23.000000
说明:
groupby('Time')
确保按时间将函数应用于每个组
KDTree
查询查找以(x\u ref,y\u ref)
为中心的给定半径的球体(这里是圆,因为这个问题是2D的,但这可以推广到nD)内的点distance\u upper\u bound
参数是独占的(即KDTree
查询只返回严格小于此值的距离),如果我们希望在半径处包含点(当closed=True
时),那么我们需要做一些额外的处理:向半径添加一小部分,然后剪裁p=2
范数(欧几里德范数),但也可以使用其他范数内是球体内的这些点
NaN
)KDTree
查询查找所有点(组内)到内点的最近距离。这方便地返回球体内点的0
(因为这是到自身的距离)其他点到最近点的距离,这就是我们的结果
系列
返回,这样熊猫们就知道如何正确地将其设置,并最终将其指定给一个名为'distance'
的列x\u ref,y\u ref
,并使用单个中心=(4,-2)
。在第一组(Time==1
)中,C
的正确距离为3.0(到a的距离),并且E
不在圆圈内
补充
如果您还想捕获每个点的最近邻:
def in_radius_dist(z,radius,closed=False):
中心=z['x_-ref','y_-ref']].mean()#它们都应该是相同的
z=z['x','y']]
距离=半径*1.0001(如果闭合),否则半径
dist,idx=KDTree(z).query(
中心,k=无,距离(上限=距离)
如果关闭:
idx=[i代表d,i在zip中(距离,idx)如果d,半径是多少?定义在哪里?修改。半径内的点记录在半径内时间列定义了一个组,对吗?这里我正确吗:对于每个组(时间),我们计算2列。(1)它是从参考点算起的半径吗,(2)到参考点半径内最近点的距离。有了这个,一个简单的if-else可以计算出你想要的列谢谢@Pierre D。很好的解释。
Time Item x y x_ref y_ref distance
0 1 A 5 -2 3 -2 0.000000 # within radius 0
1 1 B 5 0 3 -2 0.000000 # within radius 0
2 1 C 8 -2 3 -2 2.828427 # nearest within radius is E
3 1 D 3 0 3 -2 0.000000 # within radius 0
4 1 E 6 0 3 -2 0.000000 # within radius 0
5 1 F 2 4 3 -2 4.123106 # nearest within radius is D
6 2 A 6 -1 4 -2 0.000000 # within radius 0
7 2 B 7 2 4 -2 3.162278 # nearest within radius is A
8 2 C 4 -3 4 -2 0.000000 # within radius 0
9 2 D 2 4 4 -2 6.403124 # nearest within radius is A
10 2 E 7 -4 4 -2 3.162278 # nearest within radius is C or A
11 2 F 6 2 4 -2 3.000000 # nearest within radius is A