如果它们之间的欧几里得最低,则将一个数据框中的二维点替换为另一个数据框中的二维点

Replace a 2D point in one dataframe with a 2D point in another dataframe if the Euclidean between them is the lowest

我有一个数据框 df1,其中两列 V1 和 V2 代表一个点的两个坐标。

df1

V1          V2
1.30344679  0.060199021
1.256628917 0.095897457
0.954959945 0.237514922
1.240081297 0.053228255
1.35765432  0.033412217
1.228539425 0.079924064
1.080489363 0.204162117
1.27587021  0.085286683
1.44        0
0.93719247  0.310292371

还有另一个数据框 df2,其中两列 C1 和 C2 代表一个点的两个坐标。

df2

C1          C2
0.083       0.323657888
1.293934451 0.046950426
1.252872503 0.09000528
0.148131303 0.347930828

df1 和 df2 的长度不同。在此示例中,将替换 df1 中的四个点。本质上,df2 中的四个点替换 df1 中的四个点,如果它们之间的欧几里德是最低的。

我们也可以说,df2 中的每个点仅替换 df1 中最近的点。我们怎样才能做到这一点?

重复的问题:小数点后的位数是9。所以,我假设不会出现重复的问题(即df1中有多个点具有相同的欧氏距离,并且距离值最小)。如果出现,我们可以随机替换行中的任意一行吗?

所需输出:revised_df1 与 df1 长度相同,但 revised_df1 替换了 df2 中的四个点。

这是一个将数据作为列表处理的解决方案。修改它以使用数据框是留给 reader 的练习。老实说,由于这需要逐行完成,因此最好将列作为列表拉出,然后再将它们转换回来。

请注意,正如我在上面试图暗示的那样,这并不能保证“最佳”解决方案。对于 df2 中的每个点,我们选择 df1 中尚未被替换的最近点。另一种选择很可能会导致更少的总错误。

import math

df1 = [
[1.30344679 ,  0.060199021],
[1.256628917,  0.095897457],
[0.954959945,  0.237514922],
[1.240081297,  0.053228255],
[1.35765432 ,  0.033412217],
[1.228539425,  0.079924064],
[1.080489363,  0.204162117],
[1.27587021 ,  0.085286683],
[1.44       ,  0],
[0.93719247 ,  0.310292371]
]

df2 = [
[0.083      ,  0.323657888],
[1.293934451,  0.046950426],
[1.252872503,  0.09000528],
[0.148131303,  0.347930828]
]

def printer(d):
    for row in d:
        print( "%.9f %.9f" % tuple(row) )

def dist(p1,p2):
    return math.sqrt( (p1[0]-p2[0])**2 + (p1[1]-p2[1])**2 )

# For each point in df2:

print("Before")
printer(df1)

replaced = set()
for p2 in df2:
    # Compute the distance to each point in df1.
    distances = [(dist(p1,p2), i1) for (i1,p1) in enumerate(df1)]
    # Sort them by distance.
    distances.sort()
    # Pick the closest that has not already been replaced.
    top = distances.pop(0)
    while top[1] in replaced:
        top = distances.pop(0)
    # Replace it.
    df1[top[1]] = p2
    replaced.add( top[1] )

print("After")
printer(df1)

输出:

Before
1.303446790 0.060199021
1.256628917 0.095897457
0.954959945 0.237514922
1.240081297 0.053228255
1.357654320 0.033412217
1.228539425 0.079924064
1.080489363 0.204162117
1.275870210 0.085286683
1.440000000 0.000000000
0.937192470 0.310292371
After
1.293934451 0.046950426
1.252872503 0.090005280
0.148131303 0.347930828
1.240081297 0.053228255
1.357654320 0.033412217
1.228539425 0.079924064
1.080489363 0.204162117
1.275870210 0.085286683
1.440000000 0.000000000
0.083000000 0.323657888