2

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

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

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

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

4

2 回答 2

5

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

首先让我们负责消除列表中重复的后续条目。由于我们希望保持顺序,并允许不相邻的重复项,我们不能使用简单的集合。因此,如果我们有一个坐标列表,例如[(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实际上并没有返回的语句。每次调用它时,它都会将值传递回调用函数。请参阅Python 中的“yield”关键字有什么作用?以获得更好的解释。

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

def filter_duplicates_2(items): result = [] prev = None for item in items: if item != prev: result.append(item) prev = item 返回结果

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

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

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。它只是跟踪它观察到的前一个项目,并且对于它处理的每个项目,它都会产生该项目和前一个项目。它使用的唯一技巧是它使用函数调用分配prev给列表中的第一项。next()

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

for (x1, y1), (x2, y2) in pairs(filter_duplicates(coords)):
   distance = getDistance(x1, y1, x2, y2)
于 2013-04-04T08:04:11.030 回答
0

这是一种仅使用以下函数的方法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
于 2013-04-04T08:16:23.877 回答