Python:有关改进逐块代码以读取数百万点的建议

我编写了一个代码来读取Python中的* .las文件. * las文件是特殊的ascii文件,其中每行是点的x,y,z值.

我的函数读取了N.个点,并检查它们是否在points_inside_poly多边形内.

我有以下问题:

>当我到达文件末尾时,得到以下消息:LASException:“ LASReader_GetPointAt”中的LASError:点下标超出范围,因为点数在块尺寸以下.我不知道如何解决这个问题.
> a = [在xrange(len(c))中,m的file_out.write(c [m])]我使用a =以避免视频打印.这是正确的吗?
>在c = [索引中的l的块[l]]中,我创建了一个新列表c,因为我不确定替换新块是否是明智的解决方案(例如:chunk = [索引中的l的块[l]]) .
>在声明中,否则…否则,我使用通行证.这是正确的选择吗?

真的谢谢你的帮助.重要的是要改善专业人士的聆听建议!!!!

import shapefile
import numpy
import numpy as np
from numpy import nonzero
from liblas import file as lasfile
from shapely.geometry import Polygon
from matplotlib.nxutils import points_inside_poly  


# open shapefile (polygon)
sf = shapefile.Reader(poly)
shapes = sf.shapes()
# extract vertices
verts = np.array(shapes[0].points,float)

# open las file
f = lasfile.File(inFile,None,'r') # open LAS
# read "header"
h = f.header

# create a file where store the points
file_out = lasfile.File(outFile,mode='w',header= h)


chunkSize = 100000
for i in xrange(0,len(f), chunkSize):
    chunk = f[i:i+chunkSize]

    x,y = [],[]

    # extraxt x and y value for each points
    for p in xrange(len(chunk)):
        x.append(chunk[p].x)
        y.append(chunk[p].y)

    # zip all points 
    points = np.array(zip(x,y))
    # create an index where are present the points inside the polygon
    index = nonzero(points_inside_poly(points, verts))[0]

    # if index is not empty do this otherwise "pass"
    if len(index) != 0:
        c = [chunk[l] for l in index] #Is It correct to create a new list or i can replace chunck?
        # save points
        a = [file_out.write(c[m]) for m in xrange(len(c))] #use a = in order to avoid video print. Is it correct?
    else:
        pass #Is It correct to use pass?

f.close()
file_out.close()

@Roland Smith提出并由Gianni更改的代码

f = lasfile.File(inFile,None,'r') # open LAS
h = f.header
# change the software id to libLAS
h.software_id = "Gianni"
file_out = lasfile.File(outFile,mode='w',header= h)
f.close()
sf = shapefile.Reader(poly) #open shpfile
shapes = sf.shapes()
for i in xrange(len(shapes)):
    verts = np.array(shapes[i].points,float)
    inside_points = [p for p in lasfile.File(inFile,None,'r') if pnpoly(p.x, p.y, verts)]
    for p in inside_points:
        file_out.write(p)
f.close()
file_out.close()

我用这些解决方案:
1)读取f = lasfile.File(inFile,None,’r’)并且在读取头之后,因为我需要在* .las输出文件中
2)关闭文件
3)我使用inside_points = [如果pnpoly(p.x,p.y,verts)是lasfile.File(inFile,None,’r’)中的p,则为p

with lasfile.File(inFile, None, 'r') as f:
...     inside_points = [p for p in f if pnpoly(p.x, p.y, verts)]
...     

因为我总是收到此错误消息

追溯(最近一次通话):
文件“”,第1行,位于
AttributeError:_exit_

解决方法:

关于(1):

首先,为什么要使用块?只需将lasfile用作迭代器(如tutorial中所示),然后一次处理一个点.下面的操作应使用列表推导中的pnpoly函数而不是points_inside_poly将多边形内的所有点写入输出文件.

from liblas import file as lasfile
import numpy as np
from matplotlib.nxutils import pnpoly

with lasfile.File(inFile, None, 'r') as f:
    inside_points = (p for p in f if pnpoly(p.x, p.y, verts))
    with lasfile.File(outFile,mode='w',header= h) as file_out:
        for p in inside_points:
            file_out.write(p)

正上方的五行应替换整个大的for循环.让我们一一介绍它们:

> with lasfile.File(inFile …:使用此构造意味着,在with块完成时,文件将自动关闭.
>现在好了,这是完成所有工作的生成器表达式(()之间的部分).遍历输入文件(对于f中的p).多边形内的每个点(如果pnpoly(p.x,p.y,verts))都将添加到生成器中.
>我们在输出文件中使用另一个with块
>和所有点(对于inside_points中的p,这是使用生成器的地方)
>写入输出文件(file_out.write(p))

因为此方法仅将多边形内的点添加到列表中,所以您不会在不需要的点上浪费内存!

如果上面显示的方法不起作用,则应仅使用块.
使用块时,应正确处理异常.例如:

from liblas import LASException

chunkSize = 100000
for i in xrange(0,len(f), chunkSize):
    try:
        chunk = f[i:i+chunkSize]
    except LASException:
        rem = len(f)-i
        chunk = f[i:i+rem]

关于(2):很抱歉,但是我无法理解您在这里想要完成的工作. “视频打印”是什么意思?

关于(3):由于您不再使用原始块,因此可以重用该名称.请注意,在python中,“变量”只是nametag.

关于(4):您没有使用else,因此请完全省略.

上一篇:java-与“迭代次数在条目数和存储桶数之和上呈线性关系”的混淆


下一篇:Java-Google在Android上的地图绘制速度非常慢还是我使用的方式错误?