首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >KDTree复制行

KDTree复制行
EN

Stack Overflow用户
提问于 2021-11-08 08:33:11
回答 1查看 108关注 0票数 0

我有两张数据。

  1. 第一个dataframe (map)由两个列组成:"X“和"Y”。map为83150行,
  2. 第二个数据帧(cords)由两列组成:"X旋转“和"Y旋转”。coords为2702行。

目的是为map内的(X,Y)坐标和coords内的(X旋转,Y旋转)坐标找到最近的邻域。

为了做到这一点,我在coords中重复每一行31次,因为这是83150/2702。现在,coords有83762行。这意味着每个(X,Y)坐标将找到其与(X旋转,Y旋转)最近的邻域,并且在coords中将有612个坐标没有最近的邻域匹配。

这就是实现这一目标的功能:

代码语言:javascript
复制
def nearest_neighbors(df, map):
    num_pts = math.ceil(map.shape[0] / df.shape[0])
    map = map[["X", "Y"]].to_numpy()
    duplicate_cords_df = pd.DataFrame(np.repeat(df.values, num_pts, axis=0), columns=df.columns)
    duplicate_cords_sub = duplicate_cords_df[["X Rotate", "Y Rotate"]].to_numpy()
    duplicate_cords_sub = duplicate_cords_sub.to_numpy()
    list_of_dicts = []
    for row in map:
        map_tree = spatial.cKDTree(duplicate_cords_sub)
        distance, index = map_tree.query(row)
        cols = ["Map X", "Map Y", "X Rotate", "Y Rotate", "Distance"]
        map_x = row[0]
        map_y = row[1]
        coords_x = (duplicate_cords_sub[index]).flat[0]
        coords_y = (duplicate_cords_sub[index]).flat[1]
        results = [map_x, map_y, coords_x, coords_y, distance]
        results_dict = dict(zip(cols, results))
        list_of_dicts.append(results_dict)
    results_df = pd.DataFrame(list_of_dicts)
    return results_df

但是,当我检查results_df中重复数的计数时,我注意到每个(X旋转,Y旋转)坐标都被使用了不同的次数。

代码语言:javascript
复制
overall_df_dup = results_df.groupby(['X Rotate', 'Y Rotate']).size().reset_index(name='count')
print(overall_df_dup)

                X Rotate           Y Rotate   count
0                -74.25               0.00     16
1                -72.48             -12.37     28
2                -72.48              -8.84     37
3                -72.48              -5.30     43
4                -72.48              -1.77     39
...                 ...                ...    ...
2697              70.71              14.14     62
2698              72.48              -8.84     45
2699              72.48              -1.77     55
2700              72.48               1.77     47
2701              72.48               5.30     48

我检查了给KDTree函数的数据帧的重复计数,它是正确的:

代码语言:javascript
复制
coords_dup = duplicate_cords.groupby(['X Rotate', 'Y Rotate']).size().reset_index(name='count')
print(coords_dup)

                 X Rotate           Y Rotate  count
0                -74.25              -0.00     31
1                -72.48             -12.37     31
2                -72.48              -8.84     31
3                -72.48              -5.30     31
4                -72.48              -1.77     31
...                 ...                ...    ...
2697              70.71              14.14     31
2698              72.48              -8.84     31
2699              72.48              -1.77     31
2700              72.48               1.77     31
2701              72.48               5.30     31

结果的df包含的坐标比输入到KdTree函数的原始数据帧中的重复多吗?

附加问题:是否可以将每个(X旋转,Y旋转)坐标映射到30次,而只有一些(X旋转,Y旋转)映射到31次?理想情况下,我希望每个(X旋转,Y旋转)坐标被映射到30次,而不管如何。

EN

回答 1

Stack Overflow用户

发布于 2021-11-08 09:33:23

在最初的意图中可能不是正确的答案,但是这可以帮助使用KDTree

创建一个最小的可重复示例:

代码语言:javascript
复制
import pandas as pd
import numpy as np
from scipy.spatial import cKDTree

gen_coords = lambda s: np.round(np.random.randint(-100, 100, s) \
                                + np.random.random(s), 2)

df_map = pd.DataFrame(gen_coords((83150, 2)), columns=['X', 'Y'])
df_coords = pd.DataFrame(gen_coords((2702, 2)), columns=['X Rotate', 'Y Rotate'])

地图坐标:

代码语言:javascript
复制
df_coords['IDX'] = cKDTree(df_map).query(df_coords, k=30)[1].tolist()
df_coords = df_coords.explode('IDX')
df_coords[['X', 'Y']] = df_map.loc[df_coords['IDX'].tolist()].values
df_coords = df_coords.drop(columns='IDX')

产出结果:

代码语言:javascript
复制
>>> df_coords

      X Rotate  Y Rotate      X      Y
0        99.00     57.35  99.18  57.13
0        99.00     57.35  98.54  57.53
0        99.00     57.35  99.14  58.20
0        99.00     57.35  99.88  57.36
0        99.00     57.35  98.03  56.94
...        ...       ...    ...    ...
2701     92.75     -8.69  91.40  -9.74
2701     92.75     -8.69  91.75  -7.29
2701     92.75     -8.69  93.41  -7.09
2701     92.75     -8.69  94.48  -8.78
2701     92.75     -8.69  93.29 -10.36

[81060 rows x 4 columns]

>>> df_coords.value_counts(['X Rotate', 'Y Rotate'])
X Rotate  Y Rotate
-99.71    -20.20      30
 35.72     85.56      30
 34.64     76.37      30
 34.76     8.32       30
 34.90    -4.75       30
                      ..
-32.69    -44.76      30
-32.66     72.96      30
-32.63    -40.65      30
-32.61     34.91      30
 99.89     98.02      30
Length: 2702, dtype: int64
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69880572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档