Im Folgenden finden Sie den Code, mit dem ich die Schaltfläche "Verwandte Tabellen" in ArcMap repliziere. In ArcMap werden mit dieser Schaltfläche Features in einer Feature-Class oder Tabelle basierend auf der Auswahl von Features in einer anderen verwandten Feature-Class oder Tabelle ausgewählt.
In ArcMap kann ich diese Schaltfläche verwenden, um meine Auswahl in Sekundenschnelle in die zugehörige Tabelle zu verschieben. Ich konnte nichts in arcpy eingebautes finden, das die Schaltfläche repliziert, daher habe ich einige verschachtelte Schleifen verwendet, um dieselbe Aufgabe auszuführen.
Der folgende Code durchläuft eine Tabelle mit "Behandlungen". Für jede Behandlung durchläuft es eine Liste von "Bäumen". Wenn eine Übereinstimmung zwischen den ID-Feldern der Behandlung und den Bäumen gefunden wird, erfolgt eine Auswahl in der Baumebene. Sobald eine Übereinstimmung für eine Behandlung gefunden wurde, durchsucht der Code die Baumebene nicht mehr nach zusätzlichen Übereinstimmungen. Es kehrt zur Behandlungstabelle zurück, wählt die nächste Behandlung aus und durchsucht erneut die Tree-Feature-Class.
Der Code selbst funktioniert gut, ist aber quälend langsam. Die "Behandlungstabelle" hat in diesem Fall 16.000 Datensätze. Die Feature-Class "tree" enthält 60.000 Datensätze.
Gibt es eine andere effizientere Methode, um das, was ESRI tut, neu zu erstellen, wenn die Auswahl von einer Tabelle in eine andere verschoben wird? Soll ich einen Index für die Tabellen erstellen? HINWEIS: Diese Daten werden in einer SDE gespeichert.
# Create search cursor to loop through the treatments
treatments = arcpy.SearchCursor(treatment_tv)
treatment_field = "Facility_ID"
for treatment in treatments:
#Get ID of treatment
treatment_ID = treatment.getValue(treatment_field)
# Create search cursor for looping through the trees
trees = arcpy.SearchCursor(tree_fl)
tree_field = "FACILITYID"
for tree in trees:
# Get FID of tree
tree_FID = tree.getValue(tree_field)
if tree_FID == treatment_FID:
query = "FACILITYID = " + str(tree_FID)
arcpy.SelectLayerByAttribute_management(tree_fl, "REMOVE_FROM_SELECTION", query)
break
Antworten:
Zuallererst sollten Sie auf jeden Fall sicherstellen, dass Ihre Primär- und Fremdschlüsselfelder in beiden Tabellen indiziert sind. Dadurch kann das DBMS Abfragen für diese Felder wesentlich effizienter planen und ausführen.
Zweitens rufen Sie
SelectLayerByAttribute_management
eine enge, verschachtelte Schleife auf (einmal pro Baum und Behandlung). Dies ist aus mehreren Gründen äußerst ineffizient:SelectLayerByAttribute_management
Korrigieren Sie stattdessen Ihren Code so, dass Sie ihn nur einmal aufrufen und eine Where-Klausel verwenden, mit der alle zugehörigen Datensätze ausgewählt werden.Wenn ich eine Funktion aus einer anderen Antwort für die Whereclause-Konstruktionslogik entliehe, würde sie ungefähr so aussehen:
Man könnte es so nennen:
selectRelatedRecords(treatment_tv, tree_fl, "Facility_ID", "FACILITYID")
Anmerkungen:
Dies verwendet eine
arcpy.da.SearchCursor
, nur verfügbar bei 10.1. Wie @PolyGeo bereits erwähnte, sind diese Cursor viel schneller als ihre Vorgänger (arcpy.SearchCursor
). Es könnte leicht modifiziert werden, um den alten SearchCursor zu verwenden:Wenn sich Ihre SDE-Geodatabase in Oracle befindet, müssen Sie darauf hinweisen, dass die
IN
in der Funktion aus der verknüpften Antwort verwendete Anweisung auf 1000 Elemente beschränkt ist. Eine mögliche Lösung wird in dieser Antwort beschrieben , aber Sie müssen die Funktion ändern, um sie in mehrereIN
Anweisungen mit einer Länge von 1000 anstelle von einer aufzuteilen .quelle
Die obige Lösung funktioniert hervorragend und war sehr schnell. Unter Verwendung des obigen Codes und des referenzierten Codes aus dem anderen Beitrag habe ich Folgendes erstellt:
quelle