पायथन के साथ ArcGIS डेस्कटॉप का उपयोग कर एक और विशेषता में परिवर्तन के आधार पर नई विशेषता की गणना?


11

मैं विभिन्न विशेषताओं के आधार पर व्यवहार में जीपीएस समय-एन्कोडेड बिंदु डेटा के एक सेट को वर्गीकृत करने का प्रयास कर रहा हूं।

मैंने एक विशेषता बनाई है जो घर के लिए 0 है और 1 स्थान के आधार पर दूर है, और अब यात्रा को घर से दूर करना चाहते हैं (बिंदुओं का एक सेट 01111111111110एक यात्रा होगी क्योंकि यह शुरू हुआ और घर पर समाप्त हो गया)। मैंने विशेषता फ़ील्ड को जोड़ा है जिसमें यात्रा संख्याएँ होंगी, लेकिन यह नहीं पता कि फ़ील्ड की गणना कैसे की जाए ताकि यह घर / दूर के क्षेत्र पर आधारित हो।

यहाँ जीपीएस डेटा का एक उदाहरण है ("*" का उपयोग अप्रासंगिक सूचना और केवल 1, 2, आदि के रूप में अनुक्रमण समय को इंगित करने के लिए), ऊपर वर्णित "होम / अवे" संकेतक और वांछित ट्रिप इंडिकेटर, "ट्रिप", जिसे मुझे गणना करने की आवश्यकता है:

Time Lat Lon Home/Away Trip
   1   *   *         0    0
   2   *   *         1    1
   3   *   *         1    1
....
  12   *   *         1    1
  13   *   *         0    0
  14   *   *         0    0
  15   *   *         1    2
  16   *   *         1    2
.... 
  34   *   *         1    2
  35   *   *         0    0
  36   *   *         0    0
  37   *   *         1    3
....

मेरा डेटा सेट मैन्युअल रूप से जाने और विशेषता तालिका में प्रत्येक यात्रा को क्रमांकित करने के लिए बहुत बड़ा है, इसलिए घर / दूर की विशेषता का आदेश देने के आधार पर फ़ील्ड की गणना करने का कोई तरीका है और दूर बिंदुओं में से प्रत्येक "clump" को एक के रूप में नामित किया गया है ट्रिप?

ये नंगे हड्डियां हैं जो पायथन कोड की तरह लग सकती हैं (मैं कोड के साथ अनुभवी नहीं हूं)।

अभिव्यक्ति:

trip = Reclass(!home!)

Codeblock:

def Reclass(home):  
  if (home = 0):  
    return 0   
  elif (home = 1 and lastValue = 0):  
    return _(incremental numbering?)_  
  elif (home = 1 and lastValue = 1):  
    return lastValue  

मैट विल्की की अनुशंसित स्क्रिप्ट का उपयोग करने के बाद मैंने कुछ बदलाव किए हैं ताकि मेरी पहली यात्रा नंबर 1 हो, मेरी दूसरी 2 है, आदि।

यहाँ मैट से संशोधित कोड है:

import arcpy
rows = arcpy.UpdateCursor("test2")

trip = 0
for row in rows:
    if row.home == 0:
        prev = row.home
        row.TRIP = trip
        rows.updateRow(row)

    elif row.home == 1 and prev == 0:
        trip += 1
        prev = row.home
        row.TRIP = trip
        rows.updateRow(row)
        rows.next()

    elif row.home == 1 and prev == 1:
        prev = row.home
        row.TRIP = trip
        rows.updateRow(row)
        rows.next()

    row.TRIP = trip
    rows.updateRow(row)


del row, rows

तब मैं सिर्फ घर = 0 के लिए चयन करता हूं और अपने यात्रा क्षेत्र की गणना 0. 0 तक करता हूं।

जवाबों:


12

इसके लिए आप UpdateCursor का उपयोग कर सकते हैं , जो प्रत्येक रिकॉर्ड (पंक्ति) के माध्यम से फीचर क्लास या टेबल और चरणों को खोलता है।

नीचे दी गई स्क्रिप्ट इस परीक्षण डेटा पर काम करती है

+-----------------------+
| Time| Home_Away|Trip  |
+-----|----------|------+
|  1  |  0       | <nul>|
|  2  |  1       | <nul>|
|  4  |  1       | <nul>|
|  5  |  0       | <nul>|
|  6  |  0       | <nul>|
|  7  |  1       | <nul>|
|  9  |  1       | <nul>|
| 12  |  1       | <nul>|
| 13  |  0       | <nul>|
+-----------------------+

import arcpy
fc = r'D:\s\py\pyscratch.gdb\gps_points'

# open the feature class and create the cursor
rows = arcpy.UpdateCursor(fc)

trip = 0
for row in rows:
    if row.HOME_AWAY == 0:
        trip += 1           # start of new trip, increment counter
        row.TRIP = trip     # calc the TRIP field to be current trip#
        rows.updateRow(row) # save
        print "Trip %s started at %s" % (trip, row.TIME)

    # keep cycling through records until HOME_AWAY is not 1
    while row.HOME_AWAY == 1:
        row.TRIP = trip
        rows.updateRow(row)
        rows.next() # move to next record

    # this is for the trailing end of a trip, the second 0
    # print "     %s ended at %s" % (trip, row.TIME)
    row.TRIP = trip
    rows.updateRow(row)

# remove programming objects and data locks
# the data itself is left alone
del row, rows

ट्रिप ब्लॉक का अनुगामी अंत वास्तव में एक ट्रिप की शुरुआत के लिए भी चलाया जाता है, लेकिन चूंकि ट्रिप काउंटर सही है, इसलिए ट्रिप-ट्रिप-पंक्ति पर डबल कैल्क कोई फर्क नहीं पड़ता। उस ब्लॉक में प्रिंट स्टेटमेंट को हटाकर देखें कि मेरा क्या मतलब है।

पायथन स्वचालित रूप rows.next()से for row in rowsब्लॉक के लिए अंत में एक निहित जोड़ता है ।

यह डेटा अखंडता को मानता है। यह गड़बड़ कर देगा अगर कभी एक पंक्ति ( 000या 00000) में शून्य होम / दूर रिकॉर्ड की एक विषम संख्या होती है । एक यात्रा जिसमें केवल शुरुआत और स्टॉप शामिल हैं , ठीक होना चाहिए, उदाहरण के लिए एक 3 ट्रिप अनुक्रम 01..10 00 01..10, जहां रिक्त स्थान यात्राओं के बीच अंतराल को दर्शाते हैं। दूसरे शब्दों में, परिणामों को मान्य करें!


2
+1, आप इसे अपडेट कर्सर में अवश्य करें। कैलकुलेटफिल्ड टूल इस बात की गारंटी नहीं देता है कि कोड ब्लॉक केवल एक बार चलाया जाएगा, इसलिए tripचर को किसी भी समय की मनमानी संख्या को फिर से शुरू किया जा सकता है।
जेसन शहीर

यह महान काम करता है कि मेरी सभी यात्राओं में सभी बिंदुओं के लिए एक नंबर दिया जाता है, हालाँकि घर के सभी बिंदुओं को एक नया नंबर दिया जाता है (यानी मेरा डेटा घर पर उन बिंदुओं से शुरू होता है जिनकी संख्या अब 1, 2, 3, है)। ... १३६ और फिर मेरी पहली यात्रा सभी १३ 137 लेबल की है)। यह कोई बड़ी बात नहीं है क्योंकि मैं सभी "होम" बिंदुओं को 0 पर वापस ला सकता हूं, लेकिन यह अच्छा होगा यदि मेरी यात्राएं 1 से शुरू होती हैं और उसके बाद समान रूप से संख्या होती हैं। कोई सलाह?
अल्माथोम

@Alice, मैंने परीक्षण नहीं किया है, लेकिन आपको उन सभी row.TRIP = tripदो ब्लॉकों में से प्रत्येक पर टिप्पणी करने या हटाने की आवश्यकता है जो यात्रा की शुरुआत और समाप्ति को संभालते हैं। (और, यह सोचने के लिए आते हैं, rows.updateRow(row)जो अनुसरण करते हैं, क्योंकि अब वहां कुछ भी नहीं बचा है।)
मैट विल्की

गड़बड़ को सुलझा लिया! मेरी लिपि के अब तीन भाग हैं:
अल्माथोम

5

"फ़ील्ड उदाहरणों की गणना करें" के तहत ArcGIS 10 मदद से पता चलता है कि "किसी संख्यात्मक क्षेत्र के संचित मूल्य की गणना कैसे करें।" यह चाल चलेगा, बशर्ते डेटा शारीरिक रूप से इच्छित अस्थायी क्रम में हो।

इसे सीधे लागू करने के लिए, अपने [गृह / दूर] सूचक को उल्टा करें (इसे 1 से घटाएं) ताकि "0" का अर्थ "दूर" हो और "1" का अर्थ "घर" हो। मैं इस [दूर / घर] नीचे उदाहरण में कहता हूं।

उदाहरण में इसके संचयी मूल्य - [संचयी] की गणना करें।

एक जोड़ें और दो से विभाजित करें - [ट्रिप] उदाहरण में (लगभग)।

अंत में, सभी "होम" रिकॉर्ड के लिए [ट्रिप] को शून्य पर सेट करें। अब परिणाम उदाहरण से सहमत हैं:

Time Lat Lon Home/Away Trip Away/Home Cumulative 
   1   *   *         0    0         1          1
   2   *   *         1    1         0          1
   3   *   *         1    1         0          1
.... 
  12   *   *         1    1         0          1
  13   *   *         0    0         1          2
  14   *   *         0    0         1          3
  15   *   *         1    2         0          3
  16   *   *         1    2         0          3
.... 
  34   *   *         1    2         0          3
  35   *   *         0    0         1          4
  36   *   *         0    0         1          5
  37   *   *         1    3         0          5
....

रिकॉर्ड के लिए, यहां ArcGIS 10 से लिया गया कोड मदद करता है। मैंने इसे थोड़ा संशोधित किया, इसलिए यह हर कदम पर एक बार करेगा: अब आपको इसे चलाने की आवश्यकता है। यह स्पष्ट होना चाहिए कि जहां [होम / अवे] उलटा हो जाता है और जहां "1 जोड़ें, 2 से विभाजित करें" चरण होता है।

अभिव्यक्ति:

acc(!Home/Away!)

अभिव्यक्ति प्रकार:

PYTHON_9.3

कोड ब्लॉक:

t=0
def acc(i):
  global t
  if t:
    t += (1-i)
  else:
    t = 1
  if i:
    return (t+1)/2
  else:
    return 0

3
किसी भी बड़ी संख्या में रिकॉर्ड के लिए यह काम नहीं करेगा। कोडब्लॉक हर कुछ हजार पंक्तियों को फिर से चलाता है (एक पूर्ण कचरा इकट्ठा चक्र के साथ) ताकि tप्रतीत होता है यादृच्छिक स्थानों में 0 पर रीसेट हो जाए।
जेसन शेखर

2
धन्यवाद, @ जेसन: मुझे उस बग की जानकारी नहीं थी। यह एक वास्तविक शो-स्टॉपर है। <शेख़ी> मैंने सोचा था कि ArcGIS इसलिए पैमाने चाहिए था उससे कहीं अधिक छोटा खिलौना समस्याओं के लिए यह अच्छा </ शेख़ी>?
whuber

1
बग नहीं, यह वास्तव में मेमोरी लीक को कम करने का प्रयास करने के लिए VBScript कार्यान्वयन से विरासत में मिला एक कार्यान्वयन विवरण है (उपयोगकर्ताओं को प्रत्येक रिकॉर्ड के लिए सूची में शामिल करना लेकिन वास्तव में किसी भी चीज़ के लिए सूची का उपयोग करना कभी नहीं, उदाहरण के लिए)। मुझे पूरा यकीन है कि मुझे 11 में रिफ्रेश से छुटकारा मिल गया क्योंकि यह गैर-स्पष्ट व्यवहार है, लेकिन मुझे याद नहीं है।
जेसन शहीर

1
@ जैसन मेरे लिए एक नया व्यंजना है: "कार्यान्वयन विस्तार।" अन्य व्यंजनाएं "सुविधा" और "अनिर्धारित व्यवहार" हैं। एक किसी अन्य नाम से गुलाब ...
whuber

2
यहां बताया गया है कि मैं इसे कैसे देखता हूं, @ जेसन: मदद पृष्ठ मेरे द्वारा प्रस्तुत कोड प्रदान करता है। इसलिए, ESRI के हिस्से पर एक निहित जोर है कि कोड काम करता है। आपके अनुसार, यह नहीं है; वास्तव में, आपके चरित्रांकन के तहत, यह चेतावनी के बिना, चुपचाप, और अप्रत्याशित रूप से असफल हो सकता है यह सिर्फ एक बग नहीं है, यह बग का संभवतम रूप है। एक "आवधिक रीसेट" एक "फिक्स" नहीं है, यह एक kluge है जो केवल स्थिति को बदतर IMHO बनाता है।
whuber
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.