我需要创建一列,该列将由表示点之间距离的列表列表组成。我试图用一个列表理解或最有效的方式创建这个距离列表。
这是起始数据帧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)
退货:
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_1
和list_2
。