Mehrfach auftretende Werte in einer Attributtabelle finden

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.

Ralph Straumann

Ralph Straumann

Ralph Straumann (Dr. sc. nat.) hat an der Universität Zürich Geographie mit Vertiefung in GIS, Wirtschaftsgeographie und Politologie studiert.

Seit 2010 arbeitet er im Tätigkeitsfeld Systemberatung + Analytik von EBP Informatik als Senior Consultant.

Er berät Kunden bei strategischen Fragen, zu Geschäftsprozessen und Organisation sowie bezüglich Quellen, Modellierung, Workflows und Analyse mit verschiedenartigen Daten im Schnittbereich zwischen IT/GIS und Anwendungsfeldern wie Verkehr und Raumplanung.

Mail: ralph.straumann@ebp.ch

Ralph Straumann auf:

Das könnte dich auch interessieren...

5 Antworten

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

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

  3. J Allen sagt:

    Brilliant! Thanks, Ralph.

  4. Alisa sagt:

    Perfect! Thanks for saving me an hour or two.

  5. @J Allen, Alisa: You’re welcome! Glad it helped.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.