3 votos

Seleccionar puntos aleatorios de la clase de características

Tengo un shapefile que incluye 49 puntos (pozos). Quiero crear 100 redes que incluyan 20 puntos seleccionados al azar de la primera red. Cuando utilicé la herramienta de creación de puntos aleatorios, algunas redes estaban duplicadas. ¿Cómo puedo crear redes no repetitivas?

4voto

M. B. Altaie Puntos 11

Dado que necesitamos compilar una lista de IDs para un SQL IN de todos modos, usemos esa cadena como base de comparación para generar las listas únicas...

import random
import arcpy

numSets   = 100
setSize   = 20
sourceFC  = r'D:\gis_se\pick49.shp'
outputGDB = r'D:\gis_se\picked.gdb'

# Extract all IDs
rawIDs = sorted([row[0] for row in arcpy.da.SearchCursor(sourceFC,'OID@')])

# Compile unique sets
resultSets = []
while (len(resultSets) < numSets):
    candidate = list(rawIDs)
    random.shuffle(candidate)
    subset = ','.join([str(id) for id in sorted(candidate[:setSize])])
    if (subset not in resultSets):
        resultSets.append(subset)

# Export the copies to GDB (or not)
print("\n".join(sorted(resultSets)))

Al probar con "generar 10 conjuntos con 5 elegidos de entre 10" pude generar candidatos duplicados, pero cuando pasé a "generar 100 conjuntos con 20 elegidos de entre 49" no fue así, pero incluso si tu generador aleatorio es cruel, esto no generará duplicados.

2voto

Anton8000 Puntos 165

Puede que esto no sea lo que está preguntando, si es así hágamelo saber.

Esto seleccionará 20 puntos al azar 20 veces sin repeticiones:

import arcpy, random
arcpy.env.overwriteOutput=True

fc = r'C:\GIS\ArcMap_default_folder\Default.gdb\jl_riks_Intersect'
oidfield = arcpy.Describe(fc).OIDFieldName

alloids = [row[0] for row in arcpy.da.SearchCursor(fc,'OID@')] #List all object ids to select from

samples = []

#Create 20 lists of 20 oids and append to samples list
for i in range(1,21):
    sample = []
    for j in range(1,21):
        sample.append(alloids.pop(random.randint(0, len(alloids)+1)))#The oid is popped so it is removed from alloids list and cant be selected again
    samples.append(sample) 

for sample in samples: #For each sample of 20 oids
    sql = """{0} IN{1}""".format(arcpy.AddFieldDelimiters(fc, oidfield), tuple(sample))
    #'OBJECTID IN(9285, 4428, 3246, 11237, 7642, 1202, 10467, 5334, 883, 12656, 9269, 5623, 13018, 3560, 9943, 197, 11917, 6709, 246, 3659)'
    arcpy.MakeFeatureLayer_management(in_features=fc, out_layer='templyr', where_clause=sql)
    #Or select by attributes, Select, etc.

2voto

John Kramlich Puntos 286

Aquí hay un enfoque alternativo en ModelBuilder que no requiere casi ningún código que crea los subconjuntos aleatorios:

Los datos:

Data

El modelo:

Model

Los resultados (de sólo 5 iteraciones a modo de ejemplo):

enter image description here

La clave de este modelo es utilizar los propios datos de los puntos como restricción y sembrar el generador de números aleatorios en cada iteración. Tenga en cuenta que la salida de la herramienta de cálculo de valores es una condición previa, así como la configuración del entorno de semillas para el generador de números aleatorios.

  1. El iterador FOR estaba simplemente configurado para contar de 1 a 5

  2. Calcular valor está configurado como se muestra:

Calculate Value tool

  1. La creación de puntos aleatorios se configura como se muestra:

Create random points tool

Sospecho que este enfoque, tal y como ha insinuado @Vince, generará potencialmente conjuntos idénticos, al igual que cualquier otro enfoque que puedas adoptar, algo que debes comprobar Existe la herramienta Feature Compare que podría utilizarse para comparar conjuntos de datos.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X