为什么ArcPy脚本运行缓慢?


12

我有一个简单的arcpy脚本,可使用其内的多边形要素中的信息来更新点shapefile中的字段。在arcpy中完成100点需要9分钟,但是arcmap中的空间连接是瞬时的。我敢肯定有一个快速建立的方法可以解决这个问题。有人可以指出我正确的方向吗?

import took 0:00:07.085000
extent took 0:00:05.991000
one pt loop took 0:00:03.780000
one pt loop took 0:00:03.850000
one pt loop took 0:00:03.791000


import datetime
t1 = datetime.datetime.now()
import arcpy
t2 = datetime.datetime.now()
print "import took %s" %  ( t2-t1)
#set up environment
arcpy.env.workspace = "data\\"
arcpy.env.overwriteOutput = True

desc = arcpy.Describe("parcels.shp")
ext = desc.Extent
extent = (ext.XMin,ext.XMax,ext.YMin,ext.YMax)
t3 = datetime.datetime.now()
print "extent took %s" %  (t3 -t2)
fc = arcpy.CreateRandomPoints_management("", "malls.shp", "", ext, 100, "", "POINT", "")
arcpy.AddField_management("malls.shp", 'ParcelID', 'LONG')

rows = arcpy.UpdateCursor('malls.shp',"","",'ParcelID')
for row in rows:
    t4 = datetime.datetime.now()
    pt = row.Shape.getPart()
    for polyrow in arcpy.SearchCursor('parcels.shp'):
        t6 = datetime.datetime.now()
        poly = polyrow.getValue('Shape')
        if extent[0]<pt.X<extent[1] and extent[2]<pt.Y<extent[3]:
            if poly.contains(pt):
                print "works"
                row.ParcelID = polyrow.Parcels_ID
                rows.updateRow(row)
                break #we can stop looking for matches since
        t7 = datetime.datetime.now()
        "a full poly loop took %s" % (t7-t6)
    t5 = datetime.datetime.now()
    print "one pt loop took %s" % (t5-t4)


print datetime.datetime.now() -t1

4
您使用的是哪个版本的ArcGIS?10.1在arcpy.da(Data Access)模块中添加了(快得多的)游标版本。
blah238 2013年

Answers:


20

如果您需要为创建第二个游标parcels.shp,请在第一个游标的循环外进行创建。就目前而言,您的脚本正在为每一行创建一个新的游标对象,malls.shp这使您花费了所有处理时间。

...
rows = arcpy.UpdateCursor('malls.shp',"","",'ParcelID')
polyrows = arcpy.SearchCursor('parcels.shp')
for row in rows:
    t4 = datetime.datetime.now()
    pt = row.Shape.getPart()
    for polyrow in polyrows:
...

就是这样 谢谢。然后我每次想遍历第二个游标时都使用.reset()吗?看来现在只经过了1次光标。
EmdyP

嗯,您不需要重置行。确保在脚本末尾删除行对象和游标对象。否则,可能会发生有趣的事情。
杰森

我认为,如果走这条路线,每次需要重置内部循环的游标。请参阅我的答案。
blah238 2013年

10

这个问题@杰森的回答(和你原来的做法)是它不占用空间索引的优势和需要嵌套,双游标循环这是会成倍慢变得点数量的增加。

另一种可能更快的替代工作流程是,仍然可以让您就地更新点要素类(空间连接仅输出新的要素类,而不更新现有的要素类),可能是:

  1. 使用空间连接创建中间(也许在内存中)要素类
  2. 使用添加连接将中间要素类连接到现有的点要素类
  3. 使用计算字段UpdateCursor将联接字段中的值复制到现有点要素类中的字段。

2
我喜欢这种替代工作流程-即使我没有问这个问题,我仍然喜欢在这里学习新的做事方法。
杰森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.