2017-09-05 38 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