2017-09-05 2 views
1

J'essaie de filtrer les coordonnées de 2 listes prises à partir d'un fichier txt par distance, je ne peux pas comprendre ce qui ne va pas car il ne supprime pas toutes les coordonnées qui ne sont pas Ne pas passer l'instruction if si la distance est supérieure à 12 mètres, supprimer l'élément dans la liste.Python - boucle - liste de calcul de distance supprimer

code:

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 

Apparemment, je résolu le problème que je faisais tout à réécrire le code ici ... Il fonctionne parfaitement.

+0

Pourriez-vous s'il vous plaît partager des données avec nous? –

+2

La suppression d'éléments d'une liste lors d'une itération par index est problématique. Lorsque vous supprimez un élément, tous les index changent de 1. –

+0

Est-ce que x [0] correspond toujours à y [0]? Pourquoi ne pas stocker les coordonnées sous forme de paires ordonnées par liste (tuples)? Code-Apprentice a raison. Je pense que l'utilisation d'une compréhension de liste est votre meilleur pari. Pouvez-vous partager un exemple de liste de points, quelles comparaisons doivent être effectuées et à quoi devrait ressembler la liste filtrée? – RagingRoosevelt

Répondre

0

La suppression d'éléments d'une liste lors d'une itération par index est problématique. Lorsque vous supprimez un élément, tous les indices Décaler 1. J'ai deux suggestions:

  1. Utilisez un tuple pour stocker vos (x, y) paires. De cette façon, vous pouvez conserver une seule liste de paires plutôt que deux listes parallèles. Utilisez une liste de compréhension pour filtrer votre liste. Avec une fonction de prédicat simple, vous pouvez réduire votre code entier à une ou deux lignes.

+0

J'ai fait la variable keepItWorking pour éviter le problème de décalage, comment pourrais-je le faire avec une liste de compréhension? lambda? – Thriskel

+0

@Thriskel Vous pouvez utiliser une fonction lambda ou une fonction nommée pour le prédicat. –

-1

Vous n'avez pas besoin de faire la plupart des choses que vous faites. Il suffit de créer une nouvelle liste filtrée et peut-être en une ligne le long des lignes de ce fera:

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) 

(pas vraiment testé - s'il vous plaît traiter ce un pseudo-code, corrections bienvenues)

0

Voici une autre façon (peut-être pas le plus efficace mais ça marche).

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)) 

impression (tuples) peut ressembler à ceci: [(2000, 2000), (2000, 2015), (2000, 2027), (2000, 2036), (2000, 2050) , (2000, 2064), (2000, 2079), (2000, 2087), (2000, 2101), (2000, 2116)]

et impression ([calc_distance (i [0], i [ 1]) pour i dans liste (postaux (tuples, tuples [1:]))]): [15,0, 12,0, 9,0, 14,0, 14,0, 15,0, 8,0, 14,0, 15,0]

Maintenant, il peut y avoir des codes zillion plus efficaces mais pensez à ceci: Fixons la distance à 0 et pour chaque paire, par ex. ((2000, 2000), (2000, 2015)) nous ajoutons la distance et stockons l'index de cette paire si la distance est inférieure à 12. Si elle est supérieure à 12, nous réinitialisons.

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 

impression (supprimer) ressemble maintenant à ceci: [3,7]. Maintenant, nous pouvons enfin créer un nouveau tableau avec tous les tuples pertinents.

newtuples = [] 

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

impression (newtuples) ressemble à: [(2000, 2000), (2000, 2015), (2000, 2027), (2000, 2050), (2000, 2064) , (2000, 2079), (2000, 2101), (2000, 2116)]

et impression ([calc_distance (i [0], i [1]) pour i dans liste (zip (newtuples , newtuples [1:]))]) comme ceci: [15.0, 12.0, 23.0, 14.0, 15.0, 22.0, 15.0]

+0

Le but de ceci est d'exporter chaque coordonnée dans un fichier de formes avec des champs séparés, c'est pourquoi j'étais plus à l'aise de diviser les listes, mais le code semble définitivement bon – Thriskel