Suite

Sélection des 10 premiers enregistrements dans la table attributaire à l'aide d'ArcMap


J'utilise ModelBuilder dans ArcMap 10.2 pour essayer de trouver un moyen de sélectionner les 10 premiers enregistrements triés par catégorie, puis par distance. Par exemple, ma table contient 100 banques et 100 églises, ce qui correspond au champ "Catégorie", et j'ai la distance entre mon site et chaque enregistrement stocké dans le champ "Distance". Essentiellement, je veux pouvoir sélectionner les 10 banques les plus proches et les 10 églises les plus proches et exporter les enregistrements sélectionnés, à l'aide d'un outil dans ModelBuilder.

Avez-vous des suggestions?


La syntaxe SearchCursor dans les commentaires et publications précédents est obsolète et 10 fois plus lente qu'un curseur d'accès aux données si vous disposez de Desktop 10.1 ou version ultérieure. N'utilisez que des curseurs DA.

Voici mon script, en supposant que vos catégories de banques et d'églises se trouvent dans le même champ dans la classe d'entités, ce script obtiendra les dix premiers éléments pour toutes les catégories ou uniquement les catégories spécifiées si vous utilisez cette option. La fin du script créera une classe d'entités distincte des 10 premiers éléments pour toutes les catégories spécifiées qui seront triées par catégorie, puis par distance. Il est au moins 10 fois plus rapide que le tri d'un curseur.

print "Script Set Up" import arcpy # Variables définies par l'utilisateur # remplacez votre espace de travail ws = r"C:PathOptionalGDB.gdb" # remplacez vos classes d'entités en entrée et en sortie sourceFC = "Feature_Class" outDataset = "Feature_Class_TOP_10s" # remplacez vos noms de champ pour les valeurs de catégorie et de distance Category = "CATEGORY_FIELD" Distance = "DISTANCE FIELD" # Supprimez éventuellement le commentaire de la deuxième ligne et modifiez pour lister des catégories spécifiques categorySet ="# categorySet = Category " IN ('BANKS', 'EGLISES' ) AND " ### Routine scriptée qui ne devrait pas avoir besoin d'être modifiée # Définir l'espace de travail arcpy.env.workspace = ws # Créer une couche d'entités pour sélectionner les enregistrements sourceLayer = sourceFC + "Layer" arcpy.MakeFeatureLayer_management(sourceFC, sourceLayer) # Construire un where clause whereclause = categorySet + "OBJECTID > -1" # sélection des enregistrements en fonction de la clause where arcpy.SelectLayerByAttribute_management(sourceLayer, "NEW_SELECTION", whereclause) # liste de champs à trier par catégorie puis par distance puis OBJECTID champs = [Category, Distance, "[email protected]"] print "Reading records" # Construire un dictionnaire récapitulatif à partir d'un SearchCursor pour chaque catégorie. valueDict = {} avec arcpy.da.SearchCursor(sourceLayer, fields) comme searchRows : pour searchRow dans searchRows : keyValue = searchRow[0] sinon keyValue dans valueDict : # attribue une nouvelle catégorie au dictionnaire stockant une liste de chaînes triable valueDict[ keyValue] = ["%(Cat)s,%(Dist)031.15f,%(OID)020.0f" % {'Cat' : searchRow[0], 'Dist' : searchRow[1], 'OID' : searchRow [2]}] else : # lorsqu'une catégorie est déjà dans le dictionnaire, ajoutez à la liste valueDict[keyValue].append("%(Cat)s,%(Dist)031.15f,%(OID)020.0f" % { 'Cat': searchRow[0], 'Dist' : searchRow[1], 'OID' : searchRow[2]}) print "Finished Reading Records" # Construire une clause whereclause = "OBJECTID IN (" pour l'élément dans le tri (valueDict.keys()): i = 0 OIDS = "" pour OID dans trié(valueDict[item]): OIDS += str(int(OID.split(",")[2])) + "," whereclause += str(int(OID.split(",")[2])) + "," i += 1 if i >= 10: break print str(OID.split(",")[0]) + " OBJECTIDs - " + OIDS[:-1] print "" whereclause = whereclause[:-1] + ")" print whereclause # select reco rds basé sur la clause where arcpy.SelectLayerByAttribute_management(sourceLayer, "NEW_SELECTION", whereclause) ### Section facultative pour créer une classe d'entités triées des 10 premiers éléments ### Supprimer la table de sortie si elle existe si arcpy.Exists(outDataset) : arcpy.Delete_management(outDataset) ### Définir l'ordre des entités d'abord par catégorie, puis par distance sort_fields = [[Catégorie, "ASCENDING"], [Distance, "ASCENDING"]] ### Sortie triée Sélectionnée top 10 Fonctionnalités pour toutes les catégories arcpy.Sort_management(sourceLayer, outDataset, sort_fields)

Si vous souhaitez traiter les 10 premiers éléments de chaque catégorie séparément, révisez la fin du script pour :

pour l'élément dans trié(valueDict.keys()): i = 0 OIDS = "" # Construire une clause whereclause = "OBJECTID IN (" pour OID dans trié(valueDict[item]): OIDS += str(int(OID .split(",")[2])) + "," whereclause += str(int(OID.split(",")[2])) + "," i += 1 if i >= 10 : break print str(OID.split(",")[0]) + " OBJECTIDs - " + OIDS[:-1] print "" whereclause = whereclause[:-1] + ")" print whereclause # sélectionne les enregistrements en fonction de la clause where arcpy.SelectLayerByAttribute_management(sourceLayer, "NEW_SELECTION", whereclause) # Faire quelque chose avec la sélection des 10 premiers de la catégorie actuelle à ce niveau de retrait

Je pense que nous pouvons gérer cela en utilisant un arcpy.SearchCursor (J'utilise toujours le Old School SearchCursor) et l'utilisation de l'outil arcpy.Select_analysis(). Ce qui suit est probablement inefficace, mais j'espère que cela vous aidera. Cela suppose que la couche Banks and Churches est conservée dans une géodatbase de fichiers (.gdb) :

import arcpy BanksAndChurches = r'PathToBanksAndChurchesFeatureClass' arcpy.env.workspace = r'PathToOutputGDB' most_IDs = []

Tout d'abord, nous avons besoin d'un curseur de recherche pour saisir les 10 banques les plus proches et ajouter leurs OID à la liste des fonctionnalités de sortie souhaitées :

curseur = arcpy.SearchCursor(BanksAndChurches, where_clause="Category = "Banks"", sort_fields="Distance D") compteur = 1 pour la ligne du curseur : si compteur <= 10 : plus proche_IDs.append(row.getValue("OID" )) compteur += 1 del row del curseur

Faites ensuite la même chose pour les églises :

curseur = arcpy.SearchCursor(BanksAndChurches, where_clause="Category = "Churches"", sort_fields="Distance D") compteur = 1 pour la ligne dans le curseur : si compteur <= 10 : le plus proche_IDs.append(row.getValue("OID" )) compteur += 1 del row del curseur

Ensuite, prenez cette liste de 20 OID et utilisez-la pour sélectionner les 10 banques les plus proches et les 10 églises les plus proches dans un fichier de sortie :

oid_list_as_string ="pour l'élément dans les plus proches_ID : oid_list_as_string += str(item) oid_list_as_string += ',' oids = oid_list_as_string[:-1] arcpy.Select_analysis(BanksAndChurches, env.workspace + "Top20Sites("", "O + oids + ")")

Bonne chance avec ça.


Voici un exemple simple (empruntant à la fois aux réponses de Jim et de Richard) :

import arcpy fc = r'C:junkFILE_GDB.gdbExport_output_gdb' # entrée de classe d'entités field1, field2 = 'Distance', 'Type' # champs à trier et groupe fcOut = r'in_memorylah' # entité de sortie class # configurer les compteurs bankcount = 0 churchcount = 0 # start where clause whereclause = "OBJECTID IN (" # parcourir trié pour la ligne dans trié (arcpy.da.SearchCursor (fc, [field1, field2, '[email protected]']) ): if row[1] == 'Bank': if bankcount < 10: bankcount = bankcount + 1 # augmenter le compteur whereclause += str(row[2]) + ',' # ajouter à la clause where if row[1] == 'Church': if churchcount < 10: churchcount = churchcount + 1 # augmentation du compteur whereclause += str(row[2]) + ',' # add to where clause del row # finish where clause whereclause = whereclause[:- 1] + ")" # make feature layer fLayer = 'fLayer' arcpy.MakeFeatureLayer_management(fc, fLayer) # make selection arcpy.SelectLayerByAttribute_management(fLayer, "NEW_SELECTION", whereclause) # écriture dans la sortie arcpy.CopyFeatures_management(fLayer, fcOut)


Voir la vidéo: Types de sélection des données attributaire et lexportation dans Arcgis (Octobre 2021).