Python 如何在坐标上连接数据集?

Python 如何在坐标上连接数据集?,python,numpy,Python,Numpy,我正在分析数据集,需要对它们进行比较。这两个数据集各有一个索引和坐标(X,Y)。坐标不相等,因此我需要使用类似于numpy.isclose(例如atol=5)的函数 我比较的目的是找到类似的y坐标(例如,y[5]=101(数据集1),y2[7]=103(数据集2))。我需要比较相同索引的x坐标(例如,x[5]=405(数据集1),x2[7]=401(数据集2)) 我的问题是我不能将这两个isclose函数组合在一起 我试着先比较y坐标,然后比较x坐标。如果是一个单独的比较,函数也会找到其他数据。

我正在分析数据集,需要对它们进行比较。这两个数据集各有一个索引和坐标(X,Y)。坐标不相等,因此我需要使用类似于
numpy.isclose
(例如
atol=5
)的函数

我比较的目的是找到类似的y坐标(例如,
y[5]=101
(数据集1),
y2[7]=103
(数据集2))。我需要比较相同索引的x坐标(例如,
x[5]=405(数据集1),x2[7]=401(数据集2)

我的问题是我不能将这两个
isclose
函数组合在一起

我试着先比较y坐标,然后比较x坐标。如果是一个单独的比较,函数也会找到其他数据。(例如,
y[5]=101,y2[7]=103;x[5]=405,x[3]=402
)。它需要比较相同的指数(5/5和7/7)

这是可行的,但给出了错误的结果:

yres={i代表yvar中的i,如果numpy.isclose(yvar2,i,atol=5).any()}
xres={i代表xvar中的i,如果numpy.isclose(xvar2,i,atol=5).any()}
理论上,我在寻找这样的东西:

yres={i代表yvar中的i,如果numpy.isclose(yvar2,i,atol=5)。any()&i代表xvar中的i,如果numpy.isclose(xvar2,i,atol=5)。any()}
期望找到具有相似坐标的点 (例如,
y[5]=101,y2[7]=103;x[5]=405,x2[7]=401

目前我收到任何类似的数据 (例如,
y[5]=101,y2[7]=103;x[5]=405,x2[3]=402

以下输入示例(图1和图2):

在这张图片中,我需要识别4个点对(索引pict1/索引pict2):

  • 6/9
  • 7/8
  • 17/13
  • 20/14
前言 您的问题与(NNS)有关。 解决这一问题的一种方法是在空间数据库中构建一个类似的数据库

一个简单的解决方案是在中实现的

问题 在这一点上,有必要知道我们想要回答什么问题:

Q1.a)查找数据集B中在给定阈值
atol
(半径)内与a的(距离)点尽可能接近的所有点

或:

Q2.a)查找数据集B中与我的数据集a的每个点相关的
k
最近点

使用KD Tree可以回答这两个问题,我们必须意识到:

  • 问题Q1和Q2不同,答案也不同
  • Q1可以将0个或多个点映射在一起,无法保证一对一映射
  • Q2将精确地将1映射到
    k
    点,保证参考数据集中的所有点都映射到搜索数据集中的
    k
    点(前提是有足够的点)
  • Q2.a通常不等同于其对等问题Q2.b(当数据集a和b被置换时)
MCVE 让我们构建一个MCVE来解决这两个问题:

# Parameters
N = 50
atol = 50
keys = ['x', 'y']

# Trials Datasets (with different sizes, we keep it general):
df1 = pd.DataFrame(np.random.randint(0, 500, size=(N-5, 2)), columns=keys).reset_index()
df2 = pd.DataFrame(np.random.randint(0, 500, size=(N+5, 2)), columns=keys).reset_index()

# Spatial Index for Datasets:
kdt1 = KDTree(df1[keys].values, leaf_size=5, metric='euclidean')
kdt2 = KDTree(df2[keys].values, leaf_size=5, metric='euclidean')

# Answer Q2.a and Q2.b (searching for a single neighbour):
df1['kNN'] = kdt2.query(df1[keys].values, k=1, return_distance=False)[:,0]
df2['kNN'] = kdt1.query(df2[keys].values, k=1, return_distance=False)[:,0]

# Answer Q1.a and Q1.b (searching within a radius):
df1['radius'] = kdt2.query_radius(df1[keys].values, atol)
df2['radius'] = kdt1.query_radius(df2[keys].values, atol)
以下是数据集A的结果作为参考:

   index    x    y  kNN    radius
0      0   65  234   39      [39]
1      1  498   49   11      [11]
2      2   56  171   19  [29, 19]
3      3  239   43   20      [20]
4      4  347   32   50      [50]
[...]
此时,我们已经具备了在空间上连接数据所需的一切

最近邻
(k=1)
我们可以使用kNN索引加入我们的数据集:

kNN1 = df1.merge(df2[['index'] + keys], left_on='kNN', right_on='index', suffixes=('_a', '_b'))
它返回:

   index_a  x_a  y_a  kNN    radius  index_b  x_b  y_b
0        0   65  234   39      [39]       39   49  260
1        1  498   49   11      [11]       11  487    4
2        2   56  171   19  [29, 19]       19   39  186
3        3  239   43   20      [20]       20  195   33
4        4  347   32   50      [50]       50  382   32
[...]
   index_a  x_a  y_a  kNN radius  index_b  x_b  y_b
0        0   65  234   39     39       39   49  260
2        1  498   49   11     11       11  487    4
3        2   56  171   19     29       29   86  167
4        2   56  171   19     19       19   39  186
7        3  239   43   20     20       20  195   33
[...]
从图形上看,它导致:

相互的问题是关于:

我们看到映射正是
1
-to-
k=1
参考数据集中的所有点都映射到搜索数据集中的另一个点。但当我们交换引用时,答案会有所不同

半径
atol
我们还可以使用radius索引加入我们的数据集:

rad1 = df1.explode('radius')\
           .merge(df2[['index'] + keys], left_on='radius', right_on='index',
                  suffixes=('_a', '_b'))
它返回:

   index_a  x_a  y_a  kNN    radius  index_b  x_b  y_b
0        0   65  234   39      [39]       39   49  260
1        1  498   49   11      [11]       11  487    4
2        2   56  171   19  [29, 19]       19   39  186
3        3  239   43   20      [20]       20  195   33
4        4  347   32   50      [50]       50  382   32
[...]
   index_a  x_a  y_a  kNN radius  index_b  x_b  y_b
0        0   65  234   39     39       39   49  260
2        1  498   49   11     11       11  487    4
3        2   56  171   19     29       29   86  167
4        2   56  171   19     19       19   39  186
7        3  239   43   20     20       20  195   33
[...]
以图形方式:

相反的答案是等价的:

我们看到答案是相同的,但无法保证一对一的映射。有些点未映射(孤立点),有些点映射到多个点(密集邻域)。此外,它还需要一个额外的参数
atol
,必须针对给定的上下文进行调优

奖金 使用以下函数渲染图形:

def plot(A, B, join, title=''):
    X = join.loc[:,['x_a','x_b']].values
    Y = join.loc[:,['y_a','y_b']].values
    fig, axe = plt.subplots()
    axe.plot(A['x'], A['y'], 'x', label='Dataset A')
    axe.plot(B['x'], B['y'], 'x', label='Dataset B')
    for k in range(X.shape[0]):
        axe.plot(X[k,:], Y[k,:], linewidth=0.75, color='black')
    axe.set_title(title)
    axe.set_xlabel(r'$x$')
    axe.set_ylabel(r'$y$')
    axe.grid()
    axe.legend(bbox_to_anchor=(1,1), loc='upper left')
    return axe
工具书类 一些有用的参考资料:


听起来像是集群问题。你能发布输入数据的样本吗。你能提供一些细节吗。您需要最接近的点来连接,还是所有点都在公差范围内(在一个球内)?点之间的距离是否类似于距离
sqrt((x1-x2)**2+(y1-y2)**2)
,与连接标准相关?距离以像素为单位。我需要在可选择公差范围内的点。你看过吗?我不完全确定我是否了解你的问题,但我认为这正是你在寻找的。这就像熊猫一样,但是你可以使用几何体(点、线或多边形)作为索引,所以像空间连接这样的事情很容易做。谢谢你的详细回复!你说得对,这似乎是我任务的解决办法。我仍然需要比较两个数据集的问题。我得到了两张图片(两组坐标)与前缀索引(不允许更改)进行比较。正如我所看到的,这个方法使用一组坐标并自动给出索引。谢谢这个更新。我仍然看到这样一个问题:这个解决方案将每个点相互比较。我只想比较一下Dataset1和Dataset2。即使为源索引创建cloumn,它也会比较来自同一集合的数据。@Carlo,您打算加入多少个点?另一种使用GIS索引的方法见此,这是一种随机的方法。这些数据集没有显微镜图片。理论上,这些点应该相互覆盖,或者在它们之间应该有一段距离。事实上,这两张图片是用不同的滤镜制作的,因此点的强度和大小不同。由于尺寸不同,中心坐标略有不同。所以我在两张图片中寻找位置几乎相同的点。@Carlo,我已经满足了您在两个数据集之间分割数据的要求。现在由您选择最适合您的方法。干杯