Bei einem Projekt brauche ich öfters eine Funktion, die mir für ein bestimmtes Attribut in einer Attributtabelle einer Feature Class aufzeigt, ob es nur ein Mal oder mehrere Male vorkommt bzw. wie oft es insgesamt vorkommt (also eine Duplikatesuche oder eine „n-kate“-Suche).
Ich habe einen Post im ArcGIS-Forum gefunden, der eine Lösung zu dem Problem beschreibt. Kent Marten von Esri schlägt darin vor, eine Field Calculation mit Python-Codeblock zu machen und in letzterem eine Python-Liste ausserhalb der Funktion zu deklarieren, so dass die Werte, die in der Python-Liste gespeichert werden, über alle Records in der Attributtabelle hinweg persistieren.
Die Methode funktioniert, hat aber den Nachteil, dass sie statt einer genauen Anzahl nur ein binäres Resultat liefert („kommt einmal vor“, „kommt mehrmals vor“) und – schwerwiegender – dass sie das erste auftretende Duplikat nicht als solches ausweist, sondern erst das zweite bzw. alle nachfolgenden.
Tyrone Guthrie schlägt im selben Post die Funktion „Frequency“ vor. Diese wiederum finde ich nicht sehr praktisch, da sie eine neue, konsolidierte Tabelle mit „unique values“ und zugehörigen Anzahlen erstellt, statt das Resultat direkt in der Attributtabelle zu liefern. Natürlich könnte man einen anschliessenden Join ausführen, ein neues Attribut hinzufügen, die Werte für die Anzahlen kopieren und den Join wieder lösen – aber dieser Ablauf scheint auch mühsam.
Stattdessen habe ich mir schnell eine kleine Funktion gezimmert, die die Aufgabe mit einer Field Calculation direkt in der Attributtabelle löst. Sie verwendet einen Python-Dictionary (anstatt einer List wie der Vorschlag von Kent Marten). Im Field Calculator müssen die Optionen „Show Codeblock“ und „Parser: Python“ gewählt sein. In das Feld „Pre-Logic Script Code“ wird folgender Code kopiert (Namen der Feature Class und des Attributs allenfalls anpassen):
import arcpy uniqueList = {} ## Set the name of the feature class here fc = "testpoints" rows = arcpy.SearchCursor(fc) for row in rows: ## Set the name of the attribute here value = row.getValue("type") if value not in uniqueList: uniqueList[value] = 1 else: uniqueList[value] = uniqueList[value] + 1 def findIncidence(inValue): return uniqueList[inValue]
In das untere Textfeld kommt der Aufruf der im Script Code definierten Funktion („type“ ist hier der Name des Attributs, das auf Mehrdeutigkeiten überprüft werden soll):
findIncidence(!type!)
Frohes Ausprobieren – ich bin offen für Verbesserungsvorschläge.
Hallo Herr Straumann,
vielen Dank für diesen Blog. Er hat mir sehr geholfen, ein ähnliches Problem zu lösen, das ich hier ergänzen möchte. Es soll eine fortlaufende Nummer in Abhängigkeit der Wertereihenfolge eines anderen Feldes („lageindex“) vergeben werden.
So sieht der Code-Block aus:
———————————————-
import arcpy
liste = []
fc = „testfc“
rows = arcpy.SearchCursor(fc)
for row in rows:
value = row.getValue(„lageindex“)
liste.append(value)
liste.sort()
def ranking(lageindex):
rank = liste.index(lageindex)
return rank
——————————————-
In der Expression-Box steht: ranking(!LAGEINDEX!)
Mein Problem war, die Liste mit allen Datensätzen fertig sortiert zu haben, bevor die lfd. Nummer vergeben wird. Ich hatte das Sortieren zunächst in der Funktion stehen, was aber ein sehr merkwürdiges Ergebnis hervorrief.
Guten Tag Herr Elend
Vielen Dank für Ihre Rückmeldung. Es freut mich natürlich, dass mein Beitrag Ihnen bei Ihrem Problem helfen konnte! Danke auch fürs Posten Ihres Codes; der hilft dann ja allenfalls wiederum jemand anderem.
Weiterhin viel Erfolg!
Brilliant! Thanks, Ralph.
Perfect! Thanks for saving me an hour or two.
@J Allen, Alisa: You’re welcome! Glad it helped.