Como agrupar aleatoriamente X% dos pontos selecionados?

15

Quais métodos estão disponíveis no ArcGIS 10.2 para subconjunto aleatório de uma seleção de pontos. Por exemplo, na captura de tela em anexo, estou interessado em manter 20% dos pontos selecionados e excluir o restante.

insira a descrição da imagem aqui

Aaron
fonte
Bem, eu não acho que exista um método padrão para selecionar pontos aleatórios da camada. Você tentou com script python? Ou suplemento?
Marcin D

Respostas:

26

Aqui está uma função python que seleciona recursos aleatórios em uma camada com base em porcentagem, ignorando a seleção atual:

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)

Copie / cole isso no shell python no ArcMap.

Em seguida, no tipo de shell SelectRandomByPercent ("layer", num), onde layerestá o nome da sua camada e numé um número inteiro da sua porcentagem.

Seleção aleatória

Uma variação para encontrar uma seleção de subconjunto, conforme solicitado:

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)

Finalmente, mais uma variação para selecionar uma camada por uma contagem, em vez de uma porcentagem:

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
fonte
Bom uso de random.sample().
Aaron
Obrigado @Aaron. Atualizei a resposta para uma seleção de subconjunto sem exportar primeiro.
Emil Brundage
+1. Existem limitações conhecidas no comprimento da string para o sqlparâmetro?
Paul
@ Paul Acabei de testar este código para selecionar 100% dos recursos com uma camada que possui quase 4 milhões de recursos, o que resultou em um erro de memória. Portanto, embora não pareça haver um limite de string rígido, há uma dependência da memória. Há também um limite de item SQL para bancos de dados Oracle SDE, que eu publiquei em
Emil Brundage
1
A Esri usou esse código em um blog support.esri.com/en/technical-article/000013141
Emil Brundage
13

Geralmente, eu também recomendo o uso das ferramentas de ecologia espacial, conforme discutido por blah238.

No entanto, outro método que você poderia tentar seria adicionar um atributo chamado Aleatório para armazenar um número aleatório: insira a descrição da imagem aqui

Em seguida, usando a calculadora de campo nesse atributo, com o Analisador Python, use o seguinte código de bloqueio:

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

Veja a imagem abaixo:

Isso criará valores aleatórios entre 0 e 1. Em seguida, se você quiser selecionar 20% dos recursos, poderá selecionar recursos em que o valor Aleatório seja menor que 0,2. Obviamente, isso funcionará melhor com muitos recursos. Criei uma classe de recurso com apenas 7 recursos como teste e não havia valores menores que 0,2. No entanto, parece que você tem muitos recursos, portanto isso não deve importar.

insira a descrição da imagem aqui

Fezter
fonte
7
esse método retornará em média 20% dos recursos, o que, em alguns casos, seria preferido. Mas se você deseja 20% de cada vez, pode fazer o que é sugerido, classificar os recursos pelo valor aleatório e selecionar os primeiros 20%.
Llaves
A Esri usou esse processo em um blog: support.esri.com/en/technical-article/000013141
Emil Brundage
6

Há também um recurso Select anterior , com script aleatório, disponível no @StephenLead para o ArcGIS Desktop. Embora tenha sido escrito, acho, para o ArcGIS 9.xe modificado pela última vez em 2008, usei-o em 2010 às 10,0, e ainda funcionava bem.

PolyGeo
fonte
5

Você pode experimentar as Ferramentas da Hawth: http://www.spatialecology.com/htools/rndsel.php

Observe que a seleção existente não é respeitada; portanto, você deve criar uma camada de recurso a partir da seleção existente primeiro.

blah238
fonte
Infelizmente, essa versão não é compatível com o ArcGIS 9.3 e superior. Agora ele é chamado Geospatial Ambiente de Modelagem: spatialecology.com/gme
kenbuja
Bom ponto, aqui está um comando equivalente no GME: spatialecology.com/gme/rsample.htm
blah238
O conjunto de ferramentas GME não funciona "dentro" ArcGIS, pelo contrário, é uma ferramenta autônoma
Ryan Garnett
3

Aqui está outro suplemento de seleção aleatória do ArcGIS 10, a Sampling Design Tool . Isso permitirá que você selecione 20% dos recursos em seu conjunto de dados. No entanto, isso não usa um conjunto selecionado para fazer uma seleção aleatória, semelhante às restrições das Ferramentas de Hawth mencionadas por blah238.

kenbuja
fonte
0

Você também pode usar a ferramenta Subset Features . De acordo com a documentação:

Divide o conjunto de dados original em duas partes: uma parte a ser usada para modelar a estrutura espacial e produzir uma superfície, a outra a ser usada para comparar e validar a superfície de saída.

Uma desvantagem é que você precisa da extensão Geostatistical Analyst.

Ernesto561
fonte