Python,在 2 个列表列表之间迭代,查看一个列表中的值是否与另一个列表中的值相似并提取它们
Python, iterating between 2 lists of lists, seeing if values in one list are similar to values in the other and extracting them
我有两个包含笛卡尔坐标的列表列表:
LBCoord = [[1195,456],[1324,674],[5644,687],[4679,654]] #very long list
CoreCoord = [[1145,466],[1524,644],[5664,657],[4479,654]] #very long list
我想遍历这两个列表,看看 x (LBCoord[n][0]) 和 y (LBCoord[n][1]) 中的两组坐标中的任何一个是否落在用户确定的 x 和 y 范围。 (澄清一下,我正在搜索的坐标集需要在 x 范围内,并且在 LBCoord 和 CoreCoord 中的任何位置内彼此的 y 范围内)
即
#user determined x and y ranges
xRange = 3
yRange = 5
LBCoord = [[1000,400],[1324,674],[5644,687],[4679,654]] #very long list
CoreCoord = [[1145,466],[1524,644],[5664,657],[997,395]] #very long
如果 LBCoord 包含坐标 [1000,400] 并且 CoreCoord 包含 [997,395],我希望程序打印出这些坐标集(因为它们在 xRange 和 yRange 内)并继续 运行.
我试过使用嵌套的 for 循环,但这些最终会拉出 duplicates/permutations 的坐标,这是一个问题,因为在 jython 脚本中实现时很难处理。
另一个需要解决的问题是,这需要使用与 Python 2.5 和 fiji 兼容的脚本来执行,因此一些导入的工具不起作用。
如有任何帮助,我们将不胜感激!
非常感谢,
本
>>> filter(lambda x : abs(x[0][0]-x[1][0])==145 and abs(x[0][3]-x[1][4])==66 , zip(LBCoord,CoreCoord))
[([1000, 400], [1145, 466])]
对两个列表的笛卡尔积进行简单过滤即可得到您想要的结果,但 运行 时间可能不可接受。让我们从那个开始:
match_pairs = []
for current_lb_coord in LBCoord:
for current_core_coord in CoreCoord:
if abs(current_lb_coord[0] - current_core_coord[0]) <= xRange
and abs(current_lb_coord[1] - current_core_coord[1]) <= yRange:
match_pairs.append((current_lb_coord, current_core_coord))
这将创建一个元组列表,第一个是 LBCoord
,第二个是 CoreCoord
。但是,运行 可能需要很长时间,因为您需要对两个列表中的每一对进行比较 - 因此它具有 O(m * n)
复杂性。
接下来就是尝试优化它。因为您确实有两个过滤器,所以您知道如果其中一个的变化太大,那么另一个是否匹配并不重要。鉴于此,您可以按 x 坐标对两个列表进行排序。然后您可以对两个列表进行操作,寻找重叠良好的点。
对列表进行排序需要 O(n log n)
时间。完成后,您应该能够 运行 同时通过两个列表(实际上比这稍微复杂一点),因此这应该会减少一些时间。复杂性来自这样一个事实,即您可以对给定条目进行多次匹配。
在下面的代码中,我将假装只有 x 坐标重要。您应该采用此代码并将其增强以包含 y 坐标。对列表进行排序然后对两者进行操作的基本过程应该会让您获得很好的加速:
sorted_lb_coords = sorted(LBCoord)
sorted_core_coords = sorted(CoreCoord)
lb_index = core_index = 0
match_pairs = []
while lb_index < len(sorted_lb_coords) and core_index < len(sorted_core_coords):
current_lb = sorted_lb_coords[lb_index]
current_core = sorted_core_coords[core_index]
# Remember I am only considering x
if abs(current_lb - current_core) < limit:
match_pairs.append((current_lb, current_core))
# This part may also be more complex if you want all available matches.
# You could run through all the current_core entries till one was out
# of range and then reset the current_core index and increment the
# current_lb index.
if current_lb < current_core:
current_lb = current_lb + 1
else:
current_core = current_core + 1
所以这个例子已经大大简化了,但希望它能向您展示这种匹配的改进方法。
我有两个包含笛卡尔坐标的列表列表:
LBCoord = [[1195,456],[1324,674],[5644,687],[4679,654]] #very long list
CoreCoord = [[1145,466],[1524,644],[5664,657],[4479,654]] #very long list
我想遍历这两个列表,看看 x (LBCoord[n][0]) 和 y (LBCoord[n][1]) 中的两组坐标中的任何一个是否落在用户确定的 x 和 y 范围。 (澄清一下,我正在搜索的坐标集需要在 x 范围内,并且在 LBCoord 和 CoreCoord 中的任何位置内彼此的 y 范围内)
即
#user determined x and y ranges
xRange = 3
yRange = 5
LBCoord = [[1000,400],[1324,674],[5644,687],[4679,654]] #very long list
CoreCoord = [[1145,466],[1524,644],[5664,657],[997,395]] #very long
如果 LBCoord 包含坐标 [1000,400] 并且 CoreCoord 包含 [997,395],我希望程序打印出这些坐标集(因为它们在 xRange 和 yRange 内)并继续 运行.
我试过使用嵌套的 for 循环,但这些最终会拉出 duplicates/permutations 的坐标,这是一个问题,因为在 jython 脚本中实现时很难处理。
另一个需要解决的问题是,这需要使用与 Python 2.5 和 fiji 兼容的脚本来执行,因此一些导入的工具不起作用。
如有任何帮助,我们将不胜感激!
非常感谢,
本
>>> filter(lambda x : abs(x[0][0]-x[1][0])==145 and abs(x[0][3]-x[1][4])==66 , zip(LBCoord,CoreCoord))
[([1000, 400], [1145, 466])]
对两个列表的笛卡尔积进行简单过滤即可得到您想要的结果,但 运行 时间可能不可接受。让我们从那个开始:
match_pairs = []
for current_lb_coord in LBCoord:
for current_core_coord in CoreCoord:
if abs(current_lb_coord[0] - current_core_coord[0]) <= xRange
and abs(current_lb_coord[1] - current_core_coord[1]) <= yRange:
match_pairs.append((current_lb_coord, current_core_coord))
这将创建一个元组列表,第一个是 LBCoord
,第二个是 CoreCoord
。但是,运行 可能需要很长时间,因为您需要对两个列表中的每一对进行比较 - 因此它具有 O(m * n)
复杂性。
接下来就是尝试优化它。因为您确实有两个过滤器,所以您知道如果其中一个的变化太大,那么另一个是否匹配并不重要。鉴于此,您可以按 x 坐标对两个列表进行排序。然后您可以对两个列表进行操作,寻找重叠良好的点。
对列表进行排序需要 O(n log n)
时间。完成后,您应该能够 运行 同时通过两个列表(实际上比这稍微复杂一点),因此这应该会减少一些时间。复杂性来自这样一个事实,即您可以对给定条目进行多次匹配。
在下面的代码中,我将假装只有 x 坐标重要。您应该采用此代码并将其增强以包含 y 坐标。对列表进行排序然后对两者进行操作的基本过程应该会让您获得很好的加速:
sorted_lb_coords = sorted(LBCoord)
sorted_core_coords = sorted(CoreCoord)
lb_index = core_index = 0
match_pairs = []
while lb_index < len(sorted_lb_coords) and core_index < len(sorted_core_coords):
current_lb = sorted_lb_coords[lb_index]
current_core = sorted_core_coords[core_index]
# Remember I am only considering x
if abs(current_lb - current_core) < limit:
match_pairs.append((current_lb, current_core))
# This part may also be more complex if you want all available matches.
# You could run through all the current_core entries till one was out
# of range and then reset the current_core index and increment the
# current_lb index.
if current_lb < current_core:
current_lb = current_lb + 1
else:
current_core = current_core + 1
所以这个例子已经大大简化了,但希望它能向您展示这种匹配的改进方法。