Tại sao tập lệnh ArcPy chậm?


12

Tôi có một tập lệnh Arcpy đơn giản để cập nhật một trường trong shapefile điểm với thông tin từ tính năng đa giác mà nó nằm trong. Phải mất 9 phút để thực hiện 100 điểm trong Arcpy nhưng một sự tham gia không gian trong arcmap là tức thời. Tôi chắc chắn có một cách nhanh chóng để giải quyết vấn đề này. Ai đó có thể chỉ cho tôi đi đúng hướng?

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
Bạn đang ở phiên bản nào của ArcGIS? 10.1 đã thêm arcpy.damô-đun (Truy cập dữ liệu) với (nhiều) phiên bản nhanh hơn của con trỏ.
blah238

Câu trả lời:


20

Nếu bạn cần tạo một con trỏ thứ hai cho parcels.shp, hãy thực hiện bên ngoài vòng lặp cho con trỏ đầu tiên của bạn. Như hiện tại, tập lệnh của bạn đang tạo một đối tượng con trỏ mới cho mỗi hàng, trong malls.shpđó điều gì làm bạn mất tất cả thời gian xử lý đó.

...
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:
...

Đây chính xác là nó. Cảm ơn bạn. và sau đó tôi sử dụng .reset () trên con trỏ thứ hai của mình cho mỗi lần tôi muốn duyệt qua nó? Có vẻ như nó chỉ đi qua con trỏ 1 lần.
EmdyP

Hmm, bạn không cần phải thiết lập lại các hàng. Hãy chắc chắn rằng bạn đang xóa cả đối tượng hàng và đối tượng con trỏ ở cuối tập lệnh. Những điều buồn cười có thể xảy ra nếu bạn không.
Jason

Tôi nghĩ rằng con trỏ vòng lặp bên trong của không cần phải thiết lập lại mỗi lần nếu bạn đi tuyến đường này. Xem câu trả lời của tôi cho một sự thay thế.
blah238

10

Vấn đề với câu trả lời của @ Jason (và cách tiếp cận ban đầu của bạn) là nó không tận dụng được chỉ số không gian và yêu cầu một vòng lặp hai con trỏ lồng nhau, sẽ trở nên chậm hơn theo cấp số nhân khi số điểm tăng lên.

Một quy trình công việc thay thế có thể nhanh hơn trong khi vẫn cho phép bạn cập nhật lớp tính năng điểm tại chỗ (Spatial Join chỉ xuất ra một lớp tính năng mới, không cập nhật một lớp tính năng hiện có) có thể là:

  1. Sử dụng Spatial Join để tạo lớp tính năng trung gian (có thể trong bộ nhớ)
  2. Sử dụng Thêm tham gia để tham gia lớp tính năng trung gian vào lớp tính năng điểm hiện tại của bạn
  3. Sử dụng Trường tính toán hoặc Cập nhật con trỏ để sao chép các giá trị trong trường đã tham gia vào trường trong lớp tính năng điểm hiện có.

2
Tôi thích quy trình làm việc thay thế này - Tôi thích điều đó mặc dù tôi không hỏi câu hỏi Tôi vẫn đang học những cách mới để làm mọi việc ở đây.
Jason
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.