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.
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:
defSelectRandomByPercent(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"returnif percent <0:print"percent is less than zero"returnimport random
fc = arcpy.Describe(layer).catalogPath
featureCount = float (arcpy.GetCount_management(fc).getOutput (0))
count = int (featureCount * float (percent)/ float (100))ifnot 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.
Uma variação para encontrar uma seleção de subconjunto, conforme solicitado:
defSelectRandomByPercent(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"returnif percent <0:print"percent is less than zero"returnimport random
featureCount = float (arcpy.GetCount_management(layer).getOutput (0))
count = int (featureCount * float (percent)/ float (100))ifnot 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:
defSelectRandomByCount(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)
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
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:
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.
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%.
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.
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.
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.
Respostas:
Aqui está uma função python que seleciona recursos aleatórios em uma camada com base em porcentagem, ignorando a seleção atual:
Copie / cole isso no shell python no ArcMap.
Em seguida, no tipo de shell
SelectRandomByPercent ("layer", num)
, ondelayer
está o nome da sua camada enum
é um número inteiro da sua porcentagem.Uma variação para encontrar uma seleção de subconjunto, conforme solicitado:
Finalmente, mais uma variação para selecionar uma camada por uma contagem, em vez de uma porcentagem:
fonte
random.sample()
.sql
parâmetro?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:
Em seguida, usando a calculadora de campo nesse atributo, com o Analisador Python, use o seguinte código de bloqueio:
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.
fonte
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.
fonte
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.
fonte
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.
fonte
Você também pode usar a ferramenta Subset Features . De acordo com a documentação:
Uma desvantagem é que você precisa da extensão Geostatistical Analyst.
fonte