2017-09-05 76 views
1

我想从2个列表中取出距离txt文件的坐标,我找不出它出了什么问题,因为它不会删除每个坐标如果距离大于12米,则不通过if语句,删除列表中的项目。Python - 循环 - 距离计算列表删除

代码:

x = [] # contains a list of x coordinates in EPGS: 2202 
y = [] # contains a list of y coordinates in EPGS: 2202 

keepItWorking = 0 # this is supposed to avoid offset once a coordinate is deleted. 

xStore = x[0] # Stores x variable to evaluate distance and delete coordinates. 
yStore = y[0] # Stores y variable to evaluate distance and delete coordinates. 

def distance(x1, x2, y1, y2): 
    return (math.sqrt(((x2 - x1)**2) + ((y2 - y1)**2))) 

for i in range(1, len(x)): 
    try: 

     if distance(x[i - keepItWorking], xStore, y[i - keepItWorking], yStore) > 12 #if distance is greater than 12 store coordinates values and proceed to delete next coordinates with the new evaluation. 
      xStore = x[i - keepItWorking] 
      yStore = y[i - keepItWorking] 

     elif distance(x[i - keepItWorking], xStore, y[i - keepItWorking], yStore) < 12 # if distance is lower than 12 meters delete values from list. 
      del x[i - keepItWorking] 
      del y[i - keepItWorking] 
      keepItWorking = keepItWorking + 1 

    except IndexError: # avoids error when index gets out of range becouse of the items eliminations. 
     continue 

显然我固定的,而在这里重写代码,我遇到的问题...这是可以正常使用。

+0

请您与我们分享一些数据? –

+2

按索引迭代时从列表中删除元素是有问题的。当你删除一个元素时,所有的索引都会移动1. –

+0

x [0]是否总是对应​​于y [0]?为什么不把坐标存储为一个列表有序对(元组)? Code-Apprentice是对的。我认为使用列表理解是最好的选择。你能分享一个点的样本列表,需要进行哪些比较,以及你期望过滤的列表看起来像什么? – RagingRoosevelt

回答

0

按索引迭代时从列表中删除元素是有问题的。当你删除一个元素,所有的指标由1转向我有两个建议:

  1. 使用一个元组来存储您(x, y)对。通过这种方式,您可以保留一个配对列表而不是两个并行列表。

  2. 使用列表理解来过滤列表。使用简单的谓词函数,可以将整个代码缩减为一行或两行。

+0

我做了变量keepItWorking以避免转移问题,我怎么能使它与理解列表?拉姆达? – Thriskel

+0

@ Thriskel您可以对谓词使用lambda或命名函数。 –

-1

你不需要做大部分事情。只要创建沿此线一个新的过滤列表,可能一个班轮会做:

x = [] # contains a list of x coordinates in EPGS: 2202 
    y = [] # contains a list of y coordinates in EPGS: 2202 

    def distance(x1, x2, y1, y2): 
     return (math.sqrt(((x2 - x1)**2) + ((y2 - y1)**2))) 

    filtered = [(coord_x, coord_y) for coord_x, coord_y a in zip(x, y) if distance(coord_x, x[0], coord_y, y[0]) > 12] 

    filtered_x, filtered_y = zip(*filtered) 

(不是真正的考验 - 请把这个伪代码,更正欢迎)

0

这里是一个替代方法(可能不是最有效的,但它的工作原理)。

import numpy as np 
import math 

# Distance function 
def calc_distance(tuple1,tuple2): 
    return (math.sqrt(((tuple1[0]-tuple2[0])**2) + ((tuple1[1] - tuple2[1])**2))) 

# Generate some random numbers 
x = np.full(10, 2000) 
y = np.append(2000,np.random.randint(8,16,size=9)) 
y = np.cumsum(y) 
tuples = list(zip(x,y)) 

打印(元组)可以是这样的:[(2000,2000),(2000年,2015年),(2000,2027),(2000,2036),(2000年, 2050) ,(2000,2064),(2000,2079),(2000,2087),(2000,2101),(2000, 2116)]

和打印([calc_distance(I [0],I [ 1])for i in list(zip(元组,元组[1:]))]]):[15.0,12.0,9.0,14.0,14.0,15.0, 8.0,14.0,15.0]

现在可能会有更高效的代码,但请想一想: 让我们将距离设置为0并为每一对(例如, ((2000,2000),(2000,2015)),如果距离低于12,我们添加距离并存储该对的索引。如果它大于12,我们重置。

distance = 0 
remove = [] 

for ind, pair in enumerate(list(zip(tuples,tuples[1:]))): 

    distance+= calc_distance(pair[0],pair[1]) 

    if distance < 12: 
     remove.append(ind+1) # +1 because we don't compare the first index in tuples. 
    else: 
     distance = 0 

打印(删除)现在看起来是这样的:[3,7]。现在我们可以最终创建一个包含所有相关元组的新数组。

newtuples = [] 

for ind,i in enumerate(tuples): 
    if ind not in remove: 
     newtuples.append(i) 

打印(newtuples)是这样的:[(2000,2000),(2000年,2015年),(2000,2027), (2000,2050),(2000,2064) ,(2000,2079),(2000,2101),(2000, 2116)]

和打印([calc_distance(I [0],I [1]),其中i在 列表(拉链(newtuples ,newtuples [1:]))])如下:[15.0,12.0,23.0, 14.0,15.0,22.0,15.0]

+0

这是为了将每个坐标导出到带有分隔字段的shape文件中,这就是为什么我更容易划分列表的原因,但是你的代码definetly看起来不错 – Thriskel