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,因此请完全省略.
标签:performance,matplotlib,coding-style,chunked-encoding,python 来源: https://codeday.me/bug/20191127/2075004.html