ทำไมสคริปต์ ArcPy จึงช้า


12

ฉันมีสคริปต์ arcpy ง่าย ๆ ในการอัปเดตเขตข้อมูลในรูปแบบไฟล์จุดพร้อมข้อมูลจากคุณสมบัติรูปหลายเหลี่ยมที่อยู่ภายใน ใช้เวลา 9 นาทีในการทำ 100 คะแนนใน arcpy แต่การเข้าร่วมเชิงพื้นที่ใน 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โมดูล (การเข้าถึงข้อมูล) ด้วยเคอร์เซอร์เวอร์ชันที่เร็วขึ้น (มาก)
blah238

คำตอบ:


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

อืมคุณไม่จำเป็นต้องรีเซ็ตแถว ตรวจสอบให้แน่ใจว่าคุณลบทั้งวัตถุแถวและวัตถุเคอร์เซอร์ที่ท้ายสคริปต์ สิ่งที่ตลกสามารถเกิดขึ้นได้หากคุณไม่ได้
Jason

ฉันคิดว่าเคอร์เซอร์ของวงในจะต้องถูกรีเซ็ตทุกครั้งถ้าคุณไปเส้นทางนี้ ดูคำตอบของฉันสำหรับทางเลือก
blah238

10

ปัญหาเกี่ยวกับคำตอบของ @ Jason (และวิธีการดั้งเดิมของคุณ) คือมันไม่ได้ใช้ประโยชน์จากดัชนีเชิงพื้นที่และต้องใช้ลูปสองเคอร์เซอร์ซ้อนกันซึ่งจะกลายเป็นช้าลงชี้แจงเมื่อจำนวนคะแนนเพิ่มขึ้น

เวิร์กโฟลว์ทางเลือกที่อาจเร็วกว่าในขณะที่ยังคงให้คุณอัปเดตคุณลักษณะระดับจุดแทน (การรวมเชิงพื้นที่เพียงแสดงผลลัพธ์คลาสคุณลักษณะใหม่ไม่ใช่อัปเดตที่มีอยู่เดิม) อาจเป็น:

  1. ใช้Spatial Joinเพื่อสร้างคลาสคุณลักษณะกลาง (อาจอยู่ในหน่วยความจำ)
  2. ใช้เพิ่มเข้าร่วมเพื่อเข้าร่วมคลาสคุณสมบัติกลางไปยังคลาสคุณลักษณะจุดที่มีอยู่ของคุณ
  3. ใช้คำนวณเขตข้อมูลหรือUpdateCursorเพื่อคัดลอกค่าในเขตข้อมูลที่รวมไปยังเขตข้อมูลในคลาสคุณลักษณะจุดที่มีอยู่

2
ฉันชอบเวิร์กโฟลว์ทางเลือกนี้ - ฉันรักที่แม้ว่าฉันไม่ได้ถามคำถามฉันยังคงเรียนรู้วิธีการใหม่ในการทำสิ่งต่าง ๆ ที่นี่
Jason
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.