ArcPy स्क्रिप्ट धीमी क्यों है?


12

मेरे पास बहुभुज सुविधा से जानकारी के साथ एक बिंदु आकार में एक क्षेत्र को अपडेट करने के लिए एक सरल चापलूसी स्क्रिप्ट है जो यह भीतर है। अर्पी में 100 अंक करने के लिए 9 मिनट लगते हैं लेकिन आर्कमैप में एक स्थानिक जुड़ाव तात्कालिक है। मुझे यकीन है कि इस समस्या को हल करने के लिए एक त्वरित स्थापित तरीका है। क्या कोई मुझे सही दिशा दिखा सकता है?

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 23

जवाबों:


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 बार कर्सर के माध्यम से जाता है।
एमिडीपी

हम्म, आपको पंक्तियों को रीसेट करने की आवश्यकता नहीं है। सुनिश्चित करें कि आप स्क्रिप्ट के अंत में पंक्ति ऑब्जेक्ट और कर्सर ऑब्जेक्ट दोनों को हटा रहे हैं। यदि आप नहीं करते हैं तो मजेदार चीजें हो सकती हैं।
जेसन

मुझे लगता है कि यदि आप इस मार्ग पर जाते हैं तो आंतरिक लूप के कर्सर को हर बार रीसेट करने की आवश्यकता होती है। एक विकल्प के लिए मेरा जवाब देखें।
blah238

10

@ जेसन के उत्तर (और आपके मूल दृष्टिकोण) के साथ समस्या यह है कि यह स्थानिक सूचकांक का लाभ नहीं उठाता है और एक नेस्टेड, दो-कर्सर लूप की आवश्यकता होती है जो अंकों की संख्या बढ़ने के साथ-साथ तेजी से धीमा होने वाला है।

एक वैकल्पिक वर्कफ़्लो जो कि तब भी हो सकता है जब आप पॉइंट फ़ीचर क्लास को इन-प्लेस अपडेट करने दें (Spatial Join only एक नया फीचर क्लास आउटपुट करता है, न कि एक मौजूदा अपडेट)।

  1. इंटरमीडिएट (शायद-इन-मेमोरी) सुविधा वर्ग बनाने के लिए स्थानिक जुड़ाव का उपयोग करें
  2. अपने मौजूदा बिंदु सुविधा वर्ग में मध्यवर्ती सुविधा वर्ग में शामिल होने के लिए Add Join का उपयोग करें
  3. मौजूदा बिंदु सुविधा वर्ग में फ़ील्ड में शामिल फ़ील्ड में मानों की प्रतिलिपि बनाने के लिए परिकलित फ़ील्ड या किसी अद्यतनकॉरस का उपयोग करें ।

2
मुझे यह वैकल्पिक वर्कफ़्लो पसंद है - मुझे प्यार है कि भले ही मैंने यह सवाल नहीं पूछा था कि मैं अभी भी यहां चीजें करने के नए तरीके सीख रहा हूं।
जेसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.