ArcGIS Desktop kullanarak sıralı tablolara sıralı sayıları hesaplamak?


12

Bir hesaplamak için bir yolu var mı sıralı sıralı sayılarla alanını? ArcGIS Alan Hesaplama kullanarak sıralı kimlik alanı hesaplamak için Sıralama özellik sınıfı gördük ? sıralı sayıların nasıl hesaplanacağını açıklar, ancak bu her zaman sıralı sıraya göre değil, FID sırasına göre hesaplanır.

#Pre-logic Script Code:
rec=0
def autoIncrement(): 
    global rec 
    pStart = 1  
    pInterval = 1 
    if (rec == 0):  
        rec = pStart  
    else:  
        rec += pInterval  
    return rec

#Expression:
autoIncrement()

Ne yapmaya çalıştığımın bir örneği . Yıl, ay, güne göre sıralamak için gelişmiş bir sıralama kullandım ve şimdi Seqalanda sıralı numaralar olmasını istiyorum . OBJECTIDAlanımın düzgün olmadığını göreceksiniz , bu nedenle yukarıdaki kod çalışmaz.

resim açıklamasını buraya girin

Bu, Alan Hesaplayıcı'da veya arcpy'de bir Güncelleme İmleci kullanılarak yapılabilir mi?


Bir ITableSort ile ArcObjects'te bunu yapabilmelisiniz .. python'da çok fazla değil. Tablo nasıl sıralanıyor? OID ve sıralama alanı ile bir sözlüğe kadar okuyabilir, sözlüğü sıralayabilir, OID ve Değer ile başka bir sözlük oluşturabilir, ikinci sözlüğe atayarak değeri ikinciye, ardından imlece atamak için sıralı ilk sözlüğü tekrarlayabilirsiniz ... a ama biraz ArcObjects kullanmadan düşünebileceğim bu.
Michael Stimson

@ MichaelMiles-Stimson bu kötü bir fikir değil, muhtemelen bir sıralama düzeni belirlemek için sözlüklere yükleyebilir ve sonra bu değerleri Seq'e yazabilirim.
Midavalo

Daha önce böyle yaptım ve iyi çalıştı. Kodumu şu anda bulamıyorum; Tek seferlikti, muhtemelen yedek disklerimden birinde ... Karşı karşıya gelirsem cevap olarak gönderirim - bu soruya zaten iyi bir cevap olmaması şartıyla.
Michael Stimson

ArcGIS'te bunun kolayca yapılamayacağından her zaman rahatsız oldum. Halbuki MapInfo'da önemsizdir. Karşılaştığım en kolay yol, Sıralama Aracı'nı kullanmaktır, ancak bu, tekrar katılmak zorunda olduğunuz başka bir veri kümesi oluşturur.
Fezter

Python sözdiziminiz mükemmel çalışıyor, bunun için teşekkürler. Sadece ilk satırı 0 yerine 1 ile başlatmanın mümkün olup olmadığını merak ediyorum. Mümkünse bana bunun kodunu verebilirsin. İyi haftalar sonu Fred
Fred

Yanıtlar:


14

2 sıralı alana sahip "Çözüm" (artan):

mxd = arcpy.mapping.MapDocument("CURRENT")
lr=arcpy.mapping.ListLayers(mxd)[0]
tbl=arcpy.da.TableToNumPyArray(lr,("oid","A","B"))
bs=sorted(tbl, key=lambda x: (x[1], x[2]))
def sortSeq(fid,a,b):
 for i,ent in enumerate(bs):
   if ent[0]==fid: return i

--------------------------------------

sortSeq( !OID!, !A!, !B! )

resim açıklamasını buraya girin

GÜNCELLENMİŞ VERSİYON:

mxd = arcpy.mapping.MapDocument("CURRENT")
lr=arcpy.mapping.ListLayers(mxd)[0]
tbl=arcpy.da.TableToNumPyArray(lr,("oid","A","B"))
bs=sorted(tbl, key=lambda x: (x[1], x[2]))
aDict={}
for i,row in enumerate(bs):
 aDict[row[0]]=i
def sortSeq(fid):
 return aDict[fid]

-----------------------

sortSeq( !OID!)

10000 kayda görevin tamamlanması 1,5 saniye sürer. Orijinal 2 dakikadan biraz fazla sürüyor


Bu kodun ilk dört satırı her kayıt için çalıştırılıyor inanıyorum. Katmanın tüm hesaplama için yalnızca bir kez sıralanması gerektiğinden buna izin verilmemelidir. Gönderimde gösterdiğim hileyi kullanmayı düşünün veya katmanın yalnızca ilk kayıt için kayıt sıralama düzenini belirlemek için yalnızca bir kez okunduğunu gösterin.
Richard Fairhurst

@RichardFairhurst Orijinal ifademi 10 bin kayıtta test ettim, tamamlanması 2 dakika 06 saniye sürdü, modifikasyon 5 saniye iyileşme ile sonuçlandı. Her satırda ilk satırların tekrarlanmadığı anlaşılıyor. Evet alan hesap makinesi komut dosyasından çok daha yavaş olsa da
FelixIP

Aynı tabloyu hesaplamaya karşı test et. Hesaplamayı yapmak için neredeyse aynı zamanı alırlarsa, o zaman sadece bir kez işlendiği varsayımını kabul edeceğim. 2 dakika ve 6 saniye oldukça yavaştır.
Richard Fairhurst

Tamam 1,5 saniye, ilk 4 satırın her kayıt için işlenmediğini gösterir. Her neyse, sözlük her iki durumda da yoludur. Ancak, diğer alanlardaki değerler aynı olduğunda Sıra numarasının her kayıtta benzersiz olmamasını istediğimde ne yaparsınız? 1: M ilişkisinde ilgili tablo için istediğim şey bu olurdu.
Richard Fairhurst

Sözlük için +1 @RichardFairhurst. Listeyi karıştırmak orijinalimin yavaş bir parçasıydı. Benzersiz olmamakla birlikte, OP'nin büyük bir varyasyonu
FelixIP

6

Bu iki aşamalı bir işlemdir ve sonuç olarak Alan Hesaplayıcı buna çok uygun değildir. Bunu bağımsız bir komut dosyasında çalıştırmak daha iyidir. Ancak, bir hile kullanmanız koşuluyla, alan hesaplayıcısında yapılabilir. Sıralı listeden tüm değerleri genel bir sözlüğe yüklemek için bir imleç kullanmanız gerekir, ancak yalnızca ilk kaydın hesaplanması sırasında. Diğer tüm kayıtlar için, her satır için tüm tabloyu sürekli olarak yeniden okumayı önlemek amacıyla sözlük oluşturma işlemini atlamanız gerekir.

Düzgün sıralanacak bir anahtar işlevi görmek için üç alan değerinin bir demet içine yerleştirilmesi gerekir. Tüm 3 alan birleşimi değerlerinin SamplePoint tablosunda benzersiz olduğunu varsayacağım, ancak benzersiz olduğundan emin olmak için ObjectID'yi ekledim. 8. satırda yol ve şekil dosyası adını sağlamanız gerekir (ya da FelixIP'in geçerli haritadaki ilk katmanın kullanıldığı yerde kullandığı tekniği kullanabilirim). Bir anahtar için farklı alanlar kullanmak isterseniz, satır 10'daki alan listesini değiştirmeniz ve bunları satır 3 ve satır 15'teki giriş alanlarıyla eşleştirmeniz gerekir.

#Pre-logic Script Code:
relateDict = {}
def autoIncrement(myYear, myMonth, myDay, OID): 
    global relateDict  
    # only populate the dictionary if it has no keys  
    if len(relateDict) == 0:  
        # Provide the path to the relate feature class/table  
        relateFC = r"C:\Users\OWNER\Documents\ArcGIS\SamplePoints.shp"  
        # create a field list with the relate fields in sort order  
        relateFieldsList = ["Year", "Month", "Day", "OID@"]  
        # process a da search cursor to transfer the data to the dictionary  
        relateList = sorted([(r[0:]) for r in arcpy.da.SearchCursor(relateFC, relateFieldsList)])
        for relateSort in range(0, len(relateList)):
            relateDict[relateList[relateSort]] = relateSort + 1
    return relateDict[(myYear,myMonth,myDay,OID)]    

#Expression:
autoIncrement(!Year!, !Month!, !Day!, !OBJECTID!)

Yıl, Ay ve Gün alan adlarının kullanılmasını da tavsiye etmem, çünkü bunlar yalnızca şekil dosyalarında çalışır ve coğrafi veri tabanlarında izin verilmez. Bir coğrafi veritabanı, tablonun özelliklerindeki alan listesine eklemeye çalışırsanız, adları Yıl_1, Ay_1, Gün_1 olarak değiştirir.

Bu tablonun amacı, onu çok alanlı bir anahtardaki başka bir tablo / özellik sınıfıyla ilişkilendirmekse, Blogumda oluşturduğum aracı Birden Çok Alan Anahtarına Tek Alan Anahtar Aracıyla İlişkilendirme - Birden Fazla Tabaka Dayalı İki Katmanı İlişkilendirme Alan


Kopyaları nasıl işler?
FelixIP

OID'yi alan listesine ekleyin. Benzersiz olduğundan emin olmak için alan listesine OID ekledim.
Richard Fairhurst

Alternatif olarak, kopyalar varsa ve kullanıcı tüm kopyaların aynı SEQ değerine sahip olmasını isterse, for döngüsü çalıştırılmadan ve sözlüğe eklenmeden önce ObjectID'i dışarıda bırakın ve listede set () kullanın.
Richard Fairhurst

+1 Teşekkürler @RichardFairhurst, arcpy'de yazma girişimim ile aynı, ancak Alan Hesaplayıcısı
Midavalo'dan çoğunu arayabileceğinizi bilmiyordum

3

Aynı sorum vardı ama daha basit bir sorun için, sıralamak için sadece bir Alan sahip dayalı. Aşağıdaki script ile başarılı oldum:

# Pre-Logic Script Code:
# Specify that the target Map Document is the current one
mxd = arcpy.mapping.MapDocument("CURRENT")
# Specify that the target layer is the first layer in the table of 
# content
lr=arcpy.mapping.ListLayers(mxd)[0]

tbl=arcpy.da.TableToNumPyArray(lr,("fid","Name_of_sorted_Field"))
bs=sorted(tbl,key=lambda x: x[1])
aDict={}
for i,row in enumerate(bs):
 aDict[row[0]]=i
def sortSeq(fid):
 return aDict[fid]

---------------------------------------------------------------
# to run the code, the following goes in the expression window
sortSeq(!FID!)
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.