Python ile ArcGIS Desktop kullanarak başka bir özellikteki değişikliklere dayanarak yeni özellik hesaplanıyor mu?


11

Farklı özniteliklere dayalı davranışlar halinde gps zaman kodlu nokta verileri kümesi sınıflandırmak çalışıyorum.

Ben yere 0 dayalı ev için 0 ve uzak için 1 bir öznitelik oluşturduk, ve şimdi evden uzakta yolculukları numaralandırmak istiyorum (bir dizi nokta 01111111111110çünkü o başladı ve evde sona erdi). Yolculuk numaralarına sahip olacak öznitelik alanını ekledim, ancak alanın nasıl hesaplanacağını bilmiyorum, böylece ev / deplasman alanına dayanıyor.

Aşağıda GPS verilerinin bir örneği (alakasız bilgileri belirtmek ve sadece 1, 2 vb. Olarak endeksleme sürelerini belirtmek için "*" kullanılması), yukarıda açıklanan "Ev / Deplasman" göstergesi ve istenen yolculuk göstergesi "Yolculuk", hangi hesaplamak gerekir:

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

Veri kümem manuel olarak geçilemeyecek kadar büyük ve nitelik tablosundaki her bir yolculuğu numaralandırdığından, alanı home / away özelliğinin nasıl sıralandığına ve uzak noktaların her bir "kümesinin" bir yolculuk?

Bunlar Python kodu gibi görünebilir çıplak kemikleri (kod ile deneyimli değilim).

İfade:

trip = Reclass(!home!)

kod bloğu:

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  

Matt Wilkie'nin tavsiye ettiği betiği kullandıktan sonra ilk seyahatimin 1 numara, ikincimin 2 vb. Olması için bazı değişiklikler yaptım.

Matt'in modifiye edilmiş kodu:

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

Sonra sadece ev = 0'ı seçiyorum ve gezi alanımı 0'a geri hesaplıyorum. Düzgün sıralı geziler.

Yanıtlar:


12

Bunun için , özellik sınıfını veya tabloyu açan ve her kayıt (satır) boyunca adım adım ilerleyen UpdateCursor kullanabilirsiniz .

Aşağıdaki komut dosyası bu test verileri üzerinde çalışır

+-----------------------+
| 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

Açma bloğunun arka ucu aslında bir yolculuğun başlangıcı için de çalıştırılır, ancak yolculuk sayacı doğru olduğundan başlangıç-gezi satırındaki çift kireç önemli değildir. Ne demek istediğimi görmek için bu bloktaki print deyimini kaldır.

Python rows.next(), for row in rowsbloğun sonuna otomatik olarak bir örtük ekler .

Bu veri bütünlüğünü varsayar. Bir satırda ( 000veya 00000) tek bir sayıda sıfır Ev / Deplasman kaydı varsa karışıklık yaşayacaktır . Yalnızca başlatma ve durdurmadan oluşan bir yolculuk , örneğin boşlukların yolculuklar arasındaki boşlukları belirttiği 3 açma dizisi gibi iyi olmalıdır01..10 00 01..10 . Başka bir deyişle, sonuçları doğrulayın!


2
+1, bunu bir güncelleme imlecinde yapmanız GEREKİR. CalculateField aracı, kod bloğunun yalnızca bir kez çalıştırılacağını garanti etmez, bu nedenle tripdeğişken herhangi bir sayıda rasgele yeniden başlatılabilir.
Jason Scheirer

Bu, tüm seyahatlerimin seyahatteki tüm puanlar için bir sayı tahsis edilmesinde harika çalışıyor, ancak evdeki tüm noktalara yeni bir numara verildi (yani verilerim, şimdi 1, 2, 3, numaralı evdeki puanlarla başlıyor. ... 136 ve sonra ilk seyahatim 137 olarak etiketlendi). Tüm "ev" puanlarını 0'a döndürebildiğim için çok önemli değil, ancak gezilerim 1'de başladı ve ondan sonra eşit sayıda olsaydı iyi olurdu. Herhangi bir tavsiye?
AlmaThom

@Alice, test etmedim, ama yapmanız gereken tek şey, row.TRIP = tripyolculuğun başlangıcını ve sonunu işleyen iki bloğun her birinde hattı yorumlamak veya silmek . (ve düşünmeye rows.updateRow(row)
gelelim

Arızayı sıraladı! senaryomun üç kısmı var:
AlmaThom

5

"Alan örneklerini hesapla" altındaki ArcGIS 10 yardımı, "Sayısal bir alanın biriken değerinin nasıl hesaplanacağını" gösterir. Verilerin fiziksel olarak istenilen zamansal sırada olması şartıyla bu hile yapılacaktır .

Doğrudan uygulamak için, [Ev / Dışarıda] göstergenizi ters çevirin (1'den çıkarın), böylece "0" "uzakta" ve "1" "ev" anlamına gelir. Aşağıdaki örnekte buna [Uzakta / Ev] diyorum.

Örnekte kümülatif değerini - [Kümülatif] hesaplayın.

Birini ekleyin ve ikiye bölün - örnekte [Yolculuk] (neredeyse).

Son olarak, tüm "ev" kayıtları için [Gezi] öğesini sıfır olarak ayarlayın. Şimdi sonuçlar örnekle aynı fikirde:

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

Kayıt için, ArcGIS 10 yardımından alınan kod. Biraz değiştirdim, böylece her adımı bir kerede yapacak: şimdi sadece çalıştırmanız gerekiyor. [Ev / Deplasman] 'ın nerede tersine çevrildiği ve "1 ekle, 2'ye böl" adımının nerede oluştuğu açık olmalıdır.

İfade:

acc(!Home/Away!)

İfade Türü:

PYTHON_9.3

Kod Bloğu:

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
Çok sayıda kayıt için bu çalışmaz. Kod bloğu birkaç yüz bin satırda bir yeniden çalışır (tam bir çöp toplama döngüsü ile birlikte), bu yüzden trastgele görünen yerlerde 0'a sıfırlanır.
Jason Scheirer

2
Teşekkürler @Jason: Bu hatanın farkında değildim. Bu gerçek bir gösteri durdurucu. <rant>
ArcGIS'in

1
Hata değil, aslında bellek sızıntılarını en aza indirmeye çalışmak için VBScript uygulamasından devralınan bir uygulama detayıdır (kullanıcılar her kayıt için bir listeye eklenenler, ancak listeyi hiçbir şey için hiçbir zaman kullanmazlar). Eminim ki 11'deki yenilemeden kurtuldum, çünkü bu bariz bir davranış değil, ama hatırlamıyorum.
Jason Scheirer

1
@Jason Bu benim için yeni bir örtmece: "uygulama detayı". Diğer örtmeceler "özellik" ve "belgesiz davranışlardır". Başka bir isimle bir gül ...
whuber

2
İşte nasıl görüyorum, @Jason: Yardım sayfasının kendisi sunduğum kodu sağlıyor. Bu nedenle, ESRI'nin kodun çalıştığı kısmında örtülü bir iddia vardır . Size göre değil; aslında, karakterizasyonunuz altında önemli ölçüde, sessizce, uyarı vermeden ve öngörülemez şekilde başarısız olabilir . Bu sadece bir böcek değil, mümkün olan en berbat böcek türüdür. "Periyodik sıfırlama" bir "düzeltme" değildir, sadece durumu daha da kötüleştiren bir IMHO klujudur.
whuber
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.