Tengo una clase de entidad de punto bastante grande en una geodatabase de archivos (~ 4 000 000 de registros). Esta es una cuadrícula regular de puntos con una resolución de 100 m.
Necesito realizar una especie de generalización en esta capa. Para esto, creo una nueva cuadrícula donde cada punto se encuentra en el medio de 4 puntos "antiguos":
* * * *
o o o
* * * *
o o o
* * * *
[*] = punto de la cuadrícula original - [o] = punto de la nueva cuadrícula
El valor del atributo de cada nuevo punto se calcula en función de los valores ponderados de sus 4 vecinos en la cuadrícula anterior. Por lo tanto, hago un bucle en todos los puntos de mi nueva cuadrícula y, para cada uno de ellos, hago un bucle en todos los puntos de mi antigua cuadrícula, para encontrar los vecinos (comparando los valores de X e Y en la tabla de atributos). Una vez que se han encontrado 4 vecinos, nos salimos del círculo.
No hay complejidad metodológica aquí, pero mi problema es que, en base a mis primeras pruebas, este script durará semanas para completarse ...
¿Ves alguna posibilidad de hacerlo más eficiente? Algunas ideas en la parte superior de mi cabeza:
- Indice los campos X e Y => Lo hice pero no noté ningún cambio significativo en el rendimiento
- Haga una consulta espacial para encontrar los vecinos en lugar de una basada en atributos. ¿Eso realmente ayudaría? ¿Qué función espacial en ArcGIS debería hacer el trabajo? Dudo que, por ejemplo, amortiguar cada nuevo punto resulte más eficiente
- Transforme la clase de entidad en una matriz NumPy. ¿Eso ayudaría? No he trabajado mucho con NumPy hasta ahora y no me gustaría sumergirme en él a menos que alguien me diga que realmente podría ayudar a reducir el tiempo de procesamiento
- ¿Algo más?
fuente
Respuestas:
¿Qué pasa si alimentaste los puntos en una matriz numpy y usaste un árbol de cKDTree para buscar vecinos? Proceso nubes de puntos LiDAR con grandes cantidades de puntos (> 20 millones) en varios MINUTOS usando esta técnica. Hay documentación aquí para kdtree y aquí para la conversión numpy. Básicamente, lee las x, y en una matriz e itera sobre cada punto de la matriz para encontrar índices de puntos dentro de una cierta distancia (vecindad) de cada punto. Puede usar estos índices para luego calcular otros atributos.
fuente
Estoy con Barbarroja ... los cursores arcpy son increíblemente aburridos, así que solo los uso para atravesar una tabla o clase de entidad exactamente una vez. Si no puedo hacer el trabajo en un ciclo, uso el cursor para llenar otro tipo de estructura de datos y trabajar con eso.
Si no desea molestarse con numpy, simplemente haga un diccionario de python simple donde use sus coordenadas como una simple clave de texto y complete los atributos que necesita para el cálculo en una lista como el valor del elemento del diccionario.
En un segundo paso, puede obtener fácilmente los valores que necesita para calcular un punto simplemente obteniéndolos de su diccionario (que es increíblemente rápido, debido a que el diccionario tiene un índice de elementos).
fuente
Para una grilla regular, debería ser mucho más eficiente trabajar en un formato ráster. Convierta su primera cuadrícula en un ráster, puede volver a muestrear a la misma resolución utilizando un interpolador bilineal pero cambiando su imagen de salida en 1/2 píxel en X e Y, y de nuevo a los puntos si aún necesita tener puntos.
EDITAR: para reglas de decisiones complejas, puede convertir cada uno de los campos que necesita como una nueva banda ráster, luego hace cuatro copias de esas bandas y cambia su ráster en las 4 direcciones en 1/2 píxel (+50, - 50), (+ 50, + 50), (-50, -50) y (-50, + 50). Entonces puedes usar álgebra de mapas regular
fuente
Gracias a todos por su ayuda!
Finalmente encontré una forma muy no pitónica de resolver este problema ... Lo que en realidad tomaba más tiempo de computación era encontrar los 4 vecinos de cada punto. En lugar de usar los atributos X e Y (ya sea con un cursor arcpy o dentro de otra estructura de datos, como un python ditionary), terminé usando la herramienta ArcGIS Generar tabla cercana . Supongo que esto aprovecha los índices espaciales y los rendimientos son obviamente mucho más altos, sin que yo tenga que implementar el índice yo mismo.
fuente
El problema con los cursores es que puedes recorrerlos de una sola manera y no puedes retroceder. Aunque no se recomienda, puede completar las características en una estructura si planea volver a visitarlas.
Si pudo procesar sus funciones en un solo ciclo, le sugiero que habilite el reciclaje. Es un parámetro en la función de clase de función de búsqueda que permite a Python reutilizar la memoria asignada por las funciones antiguas y hacer que recorrer las funciones en un cursor sea mucho más rápido. Puede procesar su cuadrícula un 80% más rápido.
El problema es que no puede habilitar el reciclaje si planea almacenar características recuperadas de un cursor.
fuente