Python - 循环 - 距离计算列表删除

时间:2017-09-05 15:27:22

标签: python filter coordinates distance

我正在尝试按距离从txt文件中获取的2个列表中的坐标进行过滤,我无法弄清楚它出了什么问题,因为它没有删除每个没有通过if语句的坐标,如果距离大于12米,删除列表中的项目。

代码:

from __future__ import print_function, unicode_literals

import wx

class MyListCtrl ( wx.ListCtrl ):
    def OnGetItemText ( self, item, column ):
        ar = []
        for i in range ( 200000 ):
            ar.append ( i )
        return '{}'.format ( len ( ar ) )

class MyFrame ( wx.Frame ):
    lc = None
    timer = None

    def __init__ ( self, *args, **kwargs ):
        super ( MyFrame, self ).__init__ ( *args, **kwargs )
        self.timer = wx.Timer ( self )

        self.panel = wx.Panel(self, -1)
        self.panel.SetDoubleBuffered(True)

        self.lc = MyListCtrl ( self.panel, style=wx.LC_VIRTUAL|wx.LC_REPORT )
        self.lc.InsertColumn ( 0, 'Count1', width=75 )
        self.lc.InsertColumn ( 1, 'Count2', width=75 )
        self.lc.InsertColumn ( 2, 'Count3', width=75 )
        self.lc.InsertColumn ( 3, 'Count4', width=75 )
        self.lc.SetItemCount ( 1 )
        self.Bind ( wx.EVT_TIMER, self.on_timer, self.timer )
        self.Bind ( wx.EVT_CLOSE, self.on_close )

        self.Show(True)
        self.timer.Start ( 1000 )

    def on_timer ( self, event ):
        self.Freeze()
        self.lc.Refresh()
        self.Thaw()

    def on_close ( self, event ):
        self.timer.Stop()
        event.Skip()

if __name__=='__main__':
    app = wx.App ( False )
    frame = MyFrame ( None )

    frame.Show()
    app.MainLoop()

显然我修复了我在这里重写代码时遇到的问题......它运行得很好。

3 个答案:

答案 0 :(得分:0)

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

  1. 使用元组存储(x, y)对。这样,您可以保留一个对的列表而不是两个并行列表。

  2. 使用列表推导过滤列表。使用简单的谓词函数,您可以将整个代码减少到一行或两行。

答案 1 :(得分: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))
  

print(元组)可以如下所示: [(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(tuples,tuples [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
  

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

newtuples = []

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

print(newtuples)看起来像: [(2000,2000),(2000,2015),(2000,2027),   (2000,2050),(2000,2064),(2000,2079),(2000,2101),(2000,   2116)]

     

打印([calc_distance(i [0],i [1])for i in   list(zip(newtuples,newtuples [1:]))])像这样: [15.0,12.0,23.0,   14.0,15.0,22.0,15.0]

答案 2 :(得分:-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)

(未经过实际测试 - 请将此视为伪代码,欢迎更正)