Suite

Utilisation des résultats du curseur de recherche Python pour sélectionner des entités par attributs

Utilisation des résultats du curseur de recherche Python pour sélectionner des entités par attributs


Je voudrais préfacer ceci en disant que je suis très nouveau sur python et ses capacités. Mon problème est donc que lors de l'utilisation de l'espace de travail in_memory, j'ai rencontré certaines limitations lors de l'interrogation de la valeur minimale d'un champ. Ma solution de contournement consistait à créer un dictionnaire, puis à utiliser le curseur de recherche pour trouver la distance minimale. Ma méthode renvoie les résultats que je recherche mais je n'ai pas pu intégrer ces résultats dans ma sélection. Voici un extrait du code que j'utilise actuellement :

# Processus : Near arcpy.Near_analysis(newStationLayer, targetPoint, "", "NO_LOCATION", "NO_ANGLE", "") nearDist = {} avec arcpy.da.SearchCursor(newStationLayer, ("[email protected]","NEAR_DIST")) as cur : pour la ligne dans cur : nearDist[row[0]] = row[1] arcpy.AddMessage("Proche distances : %s"%str(nearDist)) ## arcpy.AddWarning(min(nearDist.iteritems() ,key=operator.itemgetter)) lowestOID = min(nearDist,key=nearDist.get) arcpy.AddWarning(lowestOID) arcpy.SelectLayerByAttribute_management()

Je le fais toujours en utilisant une fonction que j'ai trouvée à l'origine sur ce site. Il crée une clause where pour vous et fonctionne avec des listes. C'est bien, car il utilise la fonction d'ajout de délimiteurs de champs et vous n'avez donc pas à vous soucier du type de données que vous utilisez (shapefile, fgdb, etc.). Ajoutez simplement ceci à votre code quelque part, puis appelez la fonction pour créer votre clause where.

def buildWhereClause(table, champ, valueList): fieldDelimited = arcpy.AddFieldDelimiters(arcpy.Describe(table).path, field) fieldType = arcpy.ListFields(table, field)[0].type if str(fieldType) == ' String' : valueList = ["'%s'" % value for value in valueList] whereClause = "%s IN(%s)" % (fieldDelimited, ', '.join(map(str, valueList))) return whereClause

Lorsque vous avez besoin de votre clause where :

whereClause = buildWhereClause(newStationLayer, "OBJECTID", [lowestOID])

Et alors:

arcpy.SelectLayerByAttribute_management(newStationLayer, "NEW_SELECTION", whereClause)

J'ai fait les paramètres de sélection de mémoire, si ce n'est pas tout à fait correct, vous devriez au moins vous faire une idée.


Un moyen très simple d'obtenir la valeur minimale consiste à utiliser TableToNumPyArray pour convertir votre table en un tableau numpy, puis à utiliser les fonctions numpy.

depuis arcpy.da import TableToNumPyArray import numpy na = TableToNumPyArray(newStationLayer, "NEAR_DIST") numpy.min(na['NEAR_DIST'])

Vous pouvez combiner cela directement avec SelectLayerByAttribute_manager.

de arcpy.da import TableToNumPyArray import numpy field = "NEAR_DIST" na = TableToNumPyArray(newStationLayer, field) arcpy.SelectLayerByAttribute_management(newStationLayer,{}" = {}".format(field, numpy.min(na[field])))

Dans cette dernière instruction, j'utilise la fonction de format de chaîne pour insérer mon nom de champ dans la clause where et pour insérer les résultats de l'appelnumpy.minsur mon tableau de tableau. Par exemple, si votre valeur minimale était de 80,0, la clause where deviendrait'"NEAR_DIST" = 80.0'.
Si vous obtenez l'erreur :

ExecuteError : échec de l'exécution. Les paramètres ne sont pas valides. La valeur ne peut pas être une classe d'entités ERREUR 000840 : la valeur n'est pas une couche raster. ERREUR 000840 : La valeur n'est pas une couche de mosaïque. Échec de l'exécution (SelectLayerByAttribute).

Cela signifie que newStationLayer est une référence directe à une classe d'entités et non à une couche à laquelle vous pouvez appliquer une sélection. Vous devrez ajouter quelque chose comme :

layer = arcpy.MakeFeatureLayer_management(newStationLayer) arcpy.SelectLayerByAttribute_management(layer,{}" = {}".format(field, numpy.min(na[field])))

Je viens d'avoir la chance de tester cela, et c'est le bon format pour une clause in_memory where. Votre référence ànewStationLayerdoit cependant être une référence à la couche dans la carte et non une référence directe à la classe d'entités in_memory ! (Sinon, vous obtiendrez l'erreur dont j'ai parlé ci-dessus.arcpy.MakeFeatureLayer_managementajoutera une nouvelle couche à la carte en utilisant votre classe d'entités in_memory.)


Voir la vidéo: Choisissez un test de grossesse adapté à vos besoins