【问题标题】:Python, efficient way to operate on pair of coordinatesPython,对坐标对进行操作的有效方法
【发布时间】:2013-03-26 04:44:25
【问题描述】:

我有一个包含纬度和经度信息的数据文件,我将其存储为表单的元组列表

[(lat1, lon1), (lat1, lon1), (lat2, lon2), (lat3, lon3), (lat3, lon3)  ...]

如上所示,如果数据文件中的位置未更改,则连续位置(纬度、经度)可能相同。因此,这里的顺序非常重要。我感兴趣的是一种相当有效的方法来检查坐标何时发生变化,lat1, lon1 -> lat2, lon2 等,然后获取这两个坐标之间的距离。

我已经有一个函数来获取getDistance(lat1, lon1, lat2, lon2) 形式的距离,它返回这些位置之间的计算距离。我想将这些距离存储在一个列表中,以后可以从中进行一些绘图。

【问题讨论】:

  • A.请包括任何相关代码。 B. 如果我理解正确,您想根据您的函数结果从另一个列表中不同元组之间差异的结果创建一个列表? C. 你的意思是某些元组 (1,1,2,3,3) 会有重复吗?还是应该是 (1,2,3,4,5) ?
  • 我只完成了读取数据文件并将其存储在元组列表中,如图所示。是的,您是对的,该功能已经存在。我想要的是一种遍历该列表的方法,当位置发生变化时,将前一个位置和新位置传递给这个函数。
  • 请回答/评论 A、B 和 C。
  • 我个人喜欢将坐标处理为虚数。使数学更简单。
  • 你想把getDistance()对每个连续对或坐标的结果放到一个列表中,顺序是一样的吗?

标签: python list coordinates tuples


【解决方案1】:

您可以将过滤掉重复项的函数与迭代对的函数结合起来:

首先让我们来消除列表中重复的后续条目。由于我们希望保持顺序,并允许不相邻的重复,我们不能使用简单的集合。因此,如果我们是一个坐标列表,例如[(0, 0), (4, 4), (4, 4), (1, 1), (0, 0)],那么正确的输出将是[(0, 0), (4, 4), (1, 1), (0, 0)]。完成此操作的一个简单函数是:

def filter_duplicates(items):
  """A generator that ignores subsequent entires that are duplicates

  >>> items = [0, 1, 1, 2, 3, 3, 3, 4, 1]
  >>> list(filter_duplicates(items))
  [0, 1, 2, 3, 4, 1]

  """
  prev = None
  for item in items:
    if item != prev:
        yield item 
        prev = item

yield 语句就像一个return,实际上并没有返回。每次调用它时,它都会将值传递回调用函数。请参阅What does the "yield" keyword do in Python? 以获得更好的解释。

这只是遍历每个项目并将其与前一个项目进行比较。如果项目不同,它会将其返回给调用函数并将其存储为当前的前一个项目。编写此函数的另一种方法是:

def filter_duplicates_2(项目): 结果 = [] 上一页 = 无 对于项目中的项目: 如果项目!= 上一个: 结果.追加(项目) 上一页 = 项目 返回结果

虽然完成同样的事情,但这种方式最终会需要更多内存并且效率会降低,因为它必须创建一个新列表来存储所有内容。

既然我们有办法确保每个项目都与其邻居不同,我们需要计算后续对之间的距离。一个简单的方法是:

def pairs(iterable):
    """A generate over pairs of items in iterable

    >>> list(pairs([0, 8, 2, 1, 3]))
    [(0, 8), (8, 2), (2, 1), (1, 3)]

    """
    iterator = iter(iterable)
    prev = next(iterator)
    for j in iterator:
        yield prev, j
        prev = j

此函数类似于filter_duplicates 函数。它只是跟踪它观察到的前一个项目,并且对于它处理的每个项目,它都会产生该项目和前一个项目。它使用的唯一技巧是使用next() 函数调用将prev 分配给列表中的第一项。

如果我们将这两个函数结合起来,我们最终会得到:

for (x1, y1), (x2, y2) in pairs(filter_duplicates(coords)):
   distance = getDistance(x1, y1, x2, y2)

【讨论】:

  • 谢谢 Nathan,这就是我想要的 :)。几个问题,因为我是 python 的初学者。 1. 这里保留坐标的顺序吗?, 2. 你能简单解释一下pairs() 函数在这里的作用,尤其是iter(iterable) 部分吗?
  • 订单被保留。我会用解释更新答案。 :)
【解决方案2】:

这是一种仅使用 itertools 中的函数的方法:

from itertools import *

l = [...]
ks = (k for k,g in groupby(l))
t1, t2 = tee(ks)
t2.next() # advance so we get adjacent pairs
for k1, k2 in izip(t1, t2):
    # call getDistance on k1, k2

这将相邻的相等元素分组,然后使用一对tee'd 迭代器从组列表中拉出相邻的对。

只使用groupby:

l = [...]
gs = itertools.groupby(l)
last, _ = gs.next()
for k, g in gs:
    # call getDistance on (last, k)
    last = k

【讨论】:

    猜你喜欢
    • 2021-10-23
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 2019-11-18
    • 2013-08-19
    • 2022-11-25
    • 2011-12-14
    • 2017-12-25
    相关资源
    最近更新 更多