如果它们之间的欧几里得是最低的,则将一个数据帧中的 2D 点替换为另一个数据帧中的 2D 点

Posted

技术标签:

【中文标题】如果它们之间的欧几里得是最低的,则将一个数据帧中的 2D 点替换为另一个数据帧中的 2D 点【英文标题】:Replace a 2D point in one dataframe with a 2D point in another dataframe if the Euclidean between them is the lowest 【发布时间】:2022-01-14 15:37:25 【问题描述】:

我有一个数据框 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 的长度相同,但 revision_df1 已替换 df2 的四个点。

【问题讨论】:

所以,改写你所说的,你希望df1 中的每个点都替换为与df2 最接近的点吗?或者是周围的其他方式?你是双向写的。 你想要的输出是什么? @TimRoberts 是的 好吧,等一下。您不想将df1 中的所有点替换为df2 中最接近的匹配项吗?您将如何决定替换哪些点? 这并没有解决重复问题。与df2 中的四个条目最接近的点是#9、#0、#1 和#9。您将如何处理两个条目映射到同一点? 【参考方案1】:

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

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

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

【讨论】:

以上是关于如果它们之间的欧几里得是最低的,则将一个数据帧中的 2D 点替换为另一个数据帧中的 2D 点的主要内容,如果未能解决你的问题,请参考以下文章

如果日期介于第二个数据帧中的两个日期之间,则 r 标记第一个数据帧中的行

R将数据帧中的字符串匹配替换为来自另一个数据帧/数组的值

在 Pandas 数据框中计算动态时间扭曲距离

在每个元素都是列表的数据帧中运行 Scipy Linregress

R - 数据帧中的条件更新坐标列

Spark SCALA - 连接两个数据帧,其中一个数据帧中的连接值位于第二个数据帧中的两个字段之间