在 Python 中找到具有一个列表理解的两列中的点列表之间的距离

Find the distance between a list of points in two columns with one list comprehension in Python

我需要创建一个列,该列将由表示点之间距离的列表列表组成。我正在尝试以一种列表理解或最有效的方式创建此距离列表。

这是开始的数据帧df

ID        list_1              list_2
00    [(10,2),(5,7)]      [(11,3),(9,9)]
01    [(1,7)]             [(9,1)(2,1),(6,3)]
02    [(4,2),(9,4)]       [(3,7)] 

这是我想要的结尾 df 数据框。基本上对于每一行,列 list_2 中的每个元组都需要找到它自己与列 list_1.

中的每个元组之间的距离
ID        list_1              list_2               distances
00    [(10,2),(5,7)]      [(11,3),(9,9)]    [[1.41,7.21],[7.07,4.47]]
01    [(1,7)]             [(9,1)(2,1)]      [[10.0,6.08]] 

在达到最终目标之前,我最终做了六次列表理解,但我确信有更有效的方法。

我在做什么:

import pandas as pd
import math

第 1 步

df['x'] = [[s[1] for s in object_slice] for object_slice in df['list_1']]

第 2 步

df['y'] = [[s[1] for s in object_slice] for object_slice in df['list_1']]

第 3 步

df['dist_p1'] = [[(df['x'][a] - s[1],df['y'][a] - s[0]) for s in object_slice]for a, object_slice in enumerate(df['list_2'])]

第 4 步

df['dist_p2'] = [[s[0] for s in object_slice] for object_slice in df['dist_p1']]

第 5 步

df['dist_p3'] = [[s[1] for s in object_slice] for object_slice in df['dist_p1']]

第 6 步

df['distances'] = [[[round(math.hypot(s2,df['dist_p2'][a][b][c]),2) for c, s2 in enumerate(s)] for b,s in enumerate(object_slice)] for a, object_slice in enumerate(df['dist_p1'])]

OP:

您的原始代码在第 3 步抛出错误,因此我无法重现您的结果。

但是,您的示例结果中的行 00 和行 01 之间的计算逻辑似乎不一致。

因为: 在第 00

行中
[[1.41,7.21],[7.07,4.47]]=[[distance((11,3),(10,2)),distance((11,3)(5,7))],
                           [distance((9,9),(10,2)),distance((9,9),(5,7))]]

这里list_2是外循环,list_1是内循环

然而在行01,

[[10.0,6.08]] = [[distance((1,7),(9,1)), distance((1,7),(2,1))]]

这里list_1是外循环,list_2是内循环

换句话说,在您的示例结果中,第 00 行和第 01 行的嵌套循环逻辑顺序不同。


但是,如果我使用 list_1 作为外循环,我将执行以下操作。

df['distances']=df.apply(lambda row:[[round(math.hypot(i[0]-j[0],i[1]-j[1]),2) for j in row['list_2']] for i in row['list_1']],axis=1)

Returns:

    list_1              list_2              distances
0   [(10, 2), (5, 7)]   [(11, 3), (9, 9)]   [[1.41, 7.07], [7.21, 4.47]]
1   [(1, 7)]            [(9, 1), (2, 1)]    [[10.0, 6.08]]

如果需要使用list_2作为外循环,只需在lambda函数中交换list_1list_2即可。