Comment sous-définir au hasard X% des points sélectionnés?

15

Quelles méthodes sont disponibles dans ArcGIS 10.2 pour sous-définir au hasard une sélection de points. Par exemple, dans la capture d'écran ci-jointe, je souhaite conserver 20% des points sélectionnés et supprimer le reste.

entrez la description de l'image ici

Aaron
la source
Eh bien, je ne pense pas qu'il existe une méthode par défaut pour sélectionner des points aléatoires dans le calque. Avez-vous essayé avec un script python? Ou un complément?
Marcin D

Réponses:

26

Voici une fonction python qui sélectionnera des entités aléatoires dans une couche en fonction du pourcentage, en ignorant la sélection actuelle:

def SelectRandomByPercent (layer, percent):
    #layer variable is the layer name in TOC
    #percent is percent as whole number  (0-100)
    if percent > 100:
        print "percent is greater than 100"
        return
    if percent < 0:
        print "percent is less than zero"
        return
    import random
    fc = arcpy.Describe (layer).catalogPath
    featureCount = float (arcpy.GetCount_management (fc).getOutput (0))
    count = int (featureCount * float (percent) / float (100))
    if not count:
        arcpy.SelectLayerByAttribute_management (layer, "CLEAR_SELECTION")
        return
    oids = [oid for oid, in arcpy.da.SearchCursor (fc, "OID@")]
    oidFldName = arcpy.Describe (layer).OIDFieldName
    path = arcpy.Describe (layer).path
    delimOidFld = arcpy.AddFieldDelimiters (path, oidFldName)
    randOids = random.sample (oids, count)
    oidsStr = ", ".join (map (str, randOids))
    sql = "{0} IN ({1})".format (delimOidFld, oidsStr)
    arcpy.SelectLayerByAttribute_management (layer, "", sql)

Copiez / collez ceci dans le shell python dans ArcMap.

Ensuite, dans le type de shell SelectRandomByPercent ("layer", num), où layerest le nom de votre couche, et numest un nombre entier de votre pourcentage.

Sélection aléatoire

Une variante pour trouver une sélection de sous-ensemble comme demandé:

def SelectRandomByPercent (layer, percent):
    #layer variable is the layer name in TOC
    #percent is percent as whole number  (0-100)
    if percent > 100:
        print "percent is greater than 100"
        return
    if percent < 0:
        print "percent is less than zero"
        return
    import random
    featureCount = float (arcpy.GetCount_management (layer).getOutput (0))
    count = int (featureCount * float (percent) / float (100))
    if not count:
        arcpy.SelectLayerByAttribute_management (layer, "CLEAR_SELECTION")
        return
    oids = [oid for oid, in arcpy.da.SearchCursor (layer, "OID@")]
    oidFldName = arcpy.Describe (layer).OIDFieldName
    path = arcpy.Describe (layer).path
    delimOidFld = arcpy.AddFieldDelimiters (path, oidFldName)
    randOids = random.sample (oids, count)
    oidsStr = ", ".join (map (str, randOids))
    sql = "{0} IN ({1})".format (delimOidFld, oidsStr)
    arcpy.SelectLayerByAttribute_management (layer, "", sql)

Enfin, une autre variante pour sélectionner un calque par un nombre, au lieu d'un pourcentage:

def SelectRandomByCount (layer, count):
    import random
    layerCount = int (arcpy.GetCount_management (layer).getOutput (0))
    if layerCount < count:
        print "input count is greater than layer count"
        return
    oids = [oid for oid, in arcpy.da.SearchCursor (layer, "OID@")]
    oidFldName = arcpy.Describe (layer).OIDFieldName
    path = arcpy.Describe (layer).path
    delimOidFld = arcpy.AddFieldDelimiters (path, oidFldName)
    randOids = random.sample (oids, count)
    oidsStr = ", ".join (map (str, randOids))
    sql = "{0} IN ({1})".format (delimOidFld, oidsStr)
    arcpy.SelectLayerByAttribute_management (layer, "", sql)
Emil Brundage
la source
Belle utilisation de random.sample().
Aaron
Merci @Aaron. J'ai mis à jour la réponse pour une sélection de sous-ensemble sans exporter d'abord.
Emil Brundage du
+1. Existe-t-il des limitations connues sur la longueur de chaîne du sqlparamètre?
Paul
@Paul Je viens de tester ce code pour sélectionner 100% des fonctionnalités avec une couche qui a près de 4 millions de fonctionnalités, ce qui a entraîné une erreur de mémoire. Ainsi, bien qu'il ne semble pas y avoir de limite de chaîne stricte, il existe une dépendance à la mémoire. Il existe également une limite d'élément SQL pour les bases de données Oracle SDE, sur laquelle j'ai blogué
Emil Brundage
1
Esri a utilisé ce code dans un blog support.esri.com/en/technical-article/000013141
Emil Brundage
13

Généralement, je recommande également d'utiliser les outils d'écologie spatiale comme discuté par blah238.

Cependant, une autre méthode que vous pourriez essayer serait d'ajouter un attribut appelé Random pour stocker un nombre aléatoire: entrez la description de l'image ici

Ensuite, en utilisant la calculatrice de champ sur cet attribut, avec l'analyseur Python, utilisez le bloc de code suivant:

import random
def rand():
  return random.random()

Voir l'image ci-dessous:

Cela créera des valeurs aléatoires entre 0 et 1. Ensuite, si vous souhaitez sélectionner 20% des entités, vous pouvez sélectionner des entités dont la valeur aléatoire est inférieure à 0,2. Bien sûr, cela fonctionnera mieux avec de nombreuses fonctionnalités. J'ai créé une classe d'entités avec seulement 7 fonctions comme test et il n'y avait pas de valeurs inférieures à 0,2. Cependant, il semble que vous ayez beaucoup de fonctionnalités, donc cela ne devrait pas avoir d'importance.

entrez la description de l'image ici

Fezter
la source
7
cette méthode restituera en moyenne 20% des fonctionnalités, ce qui dans certains cas serait préféré. Mais si vous voulez 20% à chaque fois, vous pouvez faire comme suggéré, puis trier les entités par valeur aléatoire et sélectionner les 20 premiers%.
Llaves
Esri a utilisé ce processus dans un blog: support.esri.com/en/technical-article/000013141
Emil Brundage
6

Il existe également des fonctionnalités de sélection au hasard antérieures de @StephenLead disponibles pour ArcGIS Desktop. Bien qu'écrit, je pense, pour ArcGIS 9.x, et modifié pour la dernière fois en 2008, je l'ai utilisé vers 2010 à 10.0, et cela fonctionnait toujours bien.

PolyGeo
la source
5

Vous pouvez essayer les outils de Hawth: http://www.spatialecology.com/htools/rndsel.php

Notez que la sélection existante n'est pas respectée, vous devez donc d'abord créer une couche d'entités à partir de la sélection existante.

blah238
la source
Malheureusement, cette version n'est pas compatible avec ArcGIS 9.3 et supérieur. Maintenant, cela s'appelle Environnement de modélisation géospatiale: spatialecology.com/gme
kenbuja
Bon point, voici la commande équivalente dans GME: spatialecology.com/gme/rsample.htm
blah238
Le jeu d'outils GME ne fonctionne pas "dans" ArcGIS, mais plutôt un outil autonome
Ryan Garnett
3

Voici un autre complément de sélection aléatoire pour ArcGIS 10, l' outil de conception d'échantillonnage . Il vous permettra de sélectionner 20% des entités de votre jeu de données. Cependant, cela n'utilise pas un ensemble sélectionné pour effectuer une sélection aléatoire, similaire aux restrictions des outils de Hawth mentionnées par blah238.

kenbuja
la source
0

Vous pouvez également utiliser l' outil Fonctions de sous - ensemble . Selon la documentation:

Divise le jeu de données d'origine en deux parties: une partie à utiliser pour modéliser la structure spatiale et produire une surface, l'autre à utiliser pour comparer et valider la surface en sortie.

Un inconvénient est que vous avez besoin de l'extension Geostatistical Analyst.

Ernesto561
la source