【问题标题】:Find the distance between a list of points in two columns with one list comprehension in Python在 Python 中使用一个列表推导查找两列中的点列表之间的距离
【发布时间】:2020-12-21 05:20:53
【问题描述】:

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

这里是开始数据框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

第一步

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

第二步

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

第三步

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'])]

第四步

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'])]

【问题讨论】:

  • 在 list1 或 list2(或两者)中有多个点的地方:您希望输出的结构如何? list1 中每个点的子列表,还是 list2 中每个点的子列表?

标签: python pandas list-comprehension euclidean-distance


【解决方案1】:

操作:

您的原始代码在第 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_1list_2

【讨论】:

  • 嘿,这很好用。你能分解一下你的 lambda 函数是如何工作的吗?如果我只是尝试运行嵌套列表理解部分,它不会运行,因为你不能从另一个中减去元组。但似乎添加 lambda 函数就像另一个嵌套列出的理解,然后允许您减去值?
  • 以您的答案为基础,我能够仅使用一个列表理解来创建答案df['distances'] = [[[round(math.hypot(i[0]-j[0], i[1]-j[1]),2) for i in b]for j in df['list_2'][a]]for a,b in enumerate(df['list_1'])]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 2021-07-09
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多