Gia*_*ear 1 python optimization performance multithreading multiprocessing
我在Python 2.7(在Window OS 64bit上)编写了一个函数,以便计算参考多边形(Ref)和ESRI shapefile格式的一个或多个分段(Seg)多边形的交集区域的平均值.代码非常慢,因为我有超过2000个参考多边形,并且对于每个Ref_polygon,函数每次运行所有Seg多边形(超过7000).对不起,但功能是原型.
我想知道多处理是否可以帮助我提高循环速度或者有更多的性能解决方案.如果多处理可能是一个可能的解决方案,我希望知道优化我的以下功能的最佳方法
import numpy as np
import ogr
import osr,gdal
from shapely.geometry import Polygon
from shapely.geometry import Point
import osgeo.gdal
import osgeo.gdal as gdal
def AreaInter(reference,segmented,outFile):
# open shapefile
ref = osgeo.ogr.Open(reference)
if ref is None:
raise SystemExit('Unable to open %s' % reference)
seg = osgeo.ogr.Open(segmented)
if seg is None:
raise SystemExit('Unable to open %s' % segmented)
ref_layer = ref.GetLayer()
seg_layer = seg.GetLayer()
# create outfile
if not os.path.split(outFile)[0]:
file_path, file_name_ext = os.path.split(os.path.abspath(reference))
outFile_filename = os.path.splitext(os.path.basename(outFile))[0]
file_out = open(os.path.abspath("{0}\\{1}.txt".format(file_path, outFile_filename)), "w")
else:
file_path_name, file_ext = os.path.splitext(outFile)
file_out = open(os.path.abspath("{0}.txt".format(file_path_name)), "w")
# For each reference objects-i
for index in xrange(ref_layer.GetFeatureCount()):
ref_feature = ref_layer.GetFeature(index)
# get FID (=Feature ID)
FID = str(ref_feature.GetFID())
ref_geometry = ref_feature.GetGeometryRef()
pts = ref_geometry.GetGeometryRef(0)
points = []
for p in xrange(pts.GetPointCount()):
points.append((pts.GetX(p), pts.GetY(p)))
# convert in a shapely polygon
ref_polygon = Polygon(points)
# get the area
ref_Area = ref_polygon.area
# create an empty list
Area_seg, Area_intersect = ([] for _ in range(2))
# For each segmented objects-j
for segment in xrange(seg_layer.GetFeatureCount()):
seg_feature = seg_layer.GetFeature(segment)
seg_geometry = seg_feature.GetGeometryRef()
pts = seg_geometry.GetGeometryRef(0)
points = []
for p in xrange(pts.GetPointCount()):
points.append((pts.GetX(p), pts.GetY(p)))
seg_polygon = Polygon(points)
seg_Area.append = seg_polygon.area
# intersection (overlap) of reference object with the segmented object
intersect_polygon = ref_polygon.intersection(seg_polygon)
# area of intersection (= 0, No intersection)
intersect_Area.append = intersect_polygon.area
# Avarage for all segmented objects (because 1 or more segmented polygons can intersect with reference polygon)
seg_Area_average = numpy.average(seg_Area)
intersect_Area_average = numpy.average(intersect_Area)
file_out.write(" ".join(["%s" %i for i in [FID, ref_Area,seg_Area_average,intersect_Area_average]])+ "\n")
file_out.close()
Run Code Online (Sandbox Code Playgroud)
您可以使用多处理包,尤其是Pool类.首先创建一个函数,在for循环中执行您想要执行的所有操作,并且仅将索引作为参数:
def process_reference_object(index):
ref_feature = ref_layer.GetFeature(index)
# all your code goes here
return (" ".join(["%s" %i for i in [FID, ref_Area,seg_Area_average,intersect_Area_average]])+ "\n")
Run Code Online (Sandbox Code Playgroud)
请注意,这不会写入文件本身 - 这将是混乱的,因为您有多个进程同时写入同一文件.相反,它返回需要写入的字符串.还要注意的是有物体在这样的功能ref_layer或ref_geometry将需要达到它somehow-这取决于你如何做到这一点(你可以把process_reference_object作为该方法与他们初始化类,也可以是像刚才定义的丑陋他们全球).
然后,您创建一个流程资源池,并使用所有索引运行Pool.imap_unordered(这将根据需要将每个索引分配给不同的流程):
from multiprocessing import Pool
p = Pool() # run multiple processes
for l in p.imap_unordered(process_reference_object, range(ref_layer.GetFeatureCount())):
file_out.write(l)
Run Code Online (Sandbox Code Playgroud)
这将并行处理跨多个进程的引用对象的独立处理,并将它们写入文件(以任意顺序,注意).
| 归档时间: |
|
| 查看次数: |
1074 次 |
| 最近记录: |