32 votos

Racionalización del código Python para Big Data

Tengo un código de Python que está diseñado para tomar shapefiles de puntos a través del siguiente flujo de trabajo:

  1. Fusión de puntos
  2. Integrar los puntos, de manera que cualquier punto que se encuentre a menos de 1 m de distancia se convierten en un solo punto
  3. Crear capa de características, donde se seleccionan los puntos con z < 10
  4. Puntos de amortiguación
  5. Resolución de polígono a trama de 1 m
  6. Reclasificar, donde 1 - 9 = 1; NoData = 0

Cada shapefile tiene aproximadamente entre 250.000 y 350.000 puntos que cubren ~ 5x7 km. Los datos de puntos utilizados como entradas representan las ubicaciones de los árboles. Cada punto (es decir, árbol) tiene un valor "z" asociado que representa el radio de la copa y se utiliza en el proceso de amortiguación. Mi intención es utilizar el resultado binario final en un proceso separado para producir un raster que describa la cobertura del dosel.

Hice una prueba con cuatro shapefiles y produjo una trama de 700MB y tardó 35 minutos (procesador i5 y 8GB RAM). Viendo que voy a necesitar para ejecutar este proceso en 3500 shapefiles, agradecería cualquier consejo para agilizar el proceso (ver código adjunto). En general, ¿cuál es la mejor manera de abordar el geoprocesamiento de big data? Más concretamente, ¿hay algún ajuste en el código o en el flujo de trabajo que pueda ayudar a aumentar la eficiencia?

Editar :

Tiempo (% del total) de las tareas de geoprocesamiento:

  • Fusión = 7,6%.
  • Integrar = 7,1%.
  • Característica a Lyr = 0
  • Tampón = 8,8%.
  • Poly a Raster = 74.8%
  • Reclasificación = 1,6%.

enter image description here

# Import arcpy module
import arcpy

# Check out any necessary licenses
arcpy.CheckOutExtension("spatial")

# Script arguments
temp4 = arcpy.GetParameterAsText(0)
if temp4 == '#' or not temp4:
    temp4 = "C:\\gdrive\\temp\\temp4" # provide a default value if unspecified

Reclassification = arcpy.GetParameterAsText(1)
if Reclassification == '#' or not Reclassification:
    Reclassification = "1 9 1;NODATA 0" # provide a default value if unspecified

Multiple_Value = arcpy.GetParameterAsText(2)
if Multiple_Value == '#' or not Multiple_Value:
    Multiple_Value = "C:\\t1.shp;C:\\t2.shp;C:\\t3.shp;C:\\t4.shp" # provide a default value if unspecified

# Local variables:
temp_shp = Multiple_Value
Output_Features = temp_shp
temp2_Layer = Output_Features
temp_Buffer = temp2_Layer
temp3 = temp_Buffer

# Process: Merge
arcpy.Merge_management(Multiple_Value, temp_shp, "x \"x\" true true false 19 Double 0 0 ,First,#,C:\\#########omitted to save space

# Process: Integrate
arcpy.Integrate_management("C:\\gdrive\\temp\\temp.shp #", "1 Meters")

# Process: Make Feature Layer
arcpy.MakeFeatureLayer_management(temp_shp, temp2_Layer, "z <10", "", "x x VISIBLE NONE;y y VISIBLE NONE;z z VISIBLE NONE;Buffer Buffer VISIBLE NONE")

# Process: Buffer
arcpy.Buffer_analysis(temp2_Layer, temp_Buffer, "z", "FULL", "ROUND", "NONE", "")

# Process: Polygon to Raster
arcpy.PolygonToRaster_conversion(temp_Buffer, "BUFF_DIST", temp3, "CELL_CENTER", "NONE", "1")

# Process: Reclassify
arcpy.gp.Reclassify_sa(temp3, "Value", Reclassification, temp4, "DATA")

14voto

auramo Puntos 161

Lo primero que yo haría es monitorear la utilización de recursos de su sistema usando algo como Monitor de recursos en Windows 7 o perfmon en Vista/XP para tener una idea de si está CPU -, memoria - o IO-bound .

Si está limitado por la memoria o el IO, es probable que no pueda hacer mucho más que actualizar el hardware, reducir el tamaño del problema o cambiar el enfoque por completo.

Si determinas que estás limitado por la CPU, yo experimentaría con el multiprocessing o uno de los muchos otros módulos basados en Python paquetes de procesamiento paralelo disponible, para ver si puede utilizar más núcleos de CPU para acelerar sus operaciones.

El truco del multiprocesamiento y del paralelismo en general es encontrar un buen esquema de partición que:

  1. Permite dividir las entradas en conjuntos de trabajo más pequeños y, a continuación, recombinar los resultados de forma que tengan sentido,
  2. Añade la menor cantidad de gastos generales (algunos son inevitables en comparación con el procesamiento en serie), y
  3. Permite ajustar el tamaño del conjunto de trabajo para utilizar mejor los recursos del sistema y obtener un rendimiento óptimo.

Puedes utilizar el script que he creado en esta respuesta como punto de partida: ¿Portar el código de Avenue para producir sombras de edificios a ArcPy/Python para ArcGIS Desktop?

Véase también esta entrada del blog de ESRI Geoprocessing sobre el tema: Multiprocesamiento en Python - Enfoques y consideraciones

Creo que su caso va a ser aún más difícil debido a la naturaleza más "caja negra" de las herramientas que está utilizando, en lugar de las matrices de geometría más finas con las que estaba trabajando. Tal vez trabajando con NumPy puede ser muy útil.

También me encontré con material de lectura interesante si querías mirar más allá de arcpy:

10voto

Sork Puntos 26

Algunos cambios de algoritmo que deberían ayudarte.

Ejecute primero su selección antes de la fusión o integración. Esto reducirá significativamente las funciones posteriores que son más caras.

Tanto la fusión como la integración consumen mucha memoria, por lo que conviene ir eliminando características a medida que se introducen clases de características, e intentar hacer las fusiones en un árbol binario para mantener el tamaño de las fusiones e integraciones bajo. Por ejemplo, para cuatro shapefiles se fusionan dos shapefiles y se integran; se fusionan dos shapefiles más y se integran; se fusionan las dos clases de características resultantes y se integran.

Su cola de trabajo comienza como una cola de referencias de shapefile. También tiene una cola de resultados para colocar los resultados. El método run() para su trabajador de procesamiento paralelo hará estas operaciones: Tomar dos elementos de la cola. Si no se toma ningún elemento (la cola está vacía), termina el trabajador. Si se toma un ítem, se coloca ese ítem directamente en la cola de resultados.

Si se toman dos elementos, para cada elemento: si se trata de un archivo shape, se selecciona para z < 10 y se crea una clase de rasgo en memoria; si no, ya es una clase de rasgo en memoria y se omite el paso de selección. Combine las dos clases de características en memoria para crear una nueva clase de características en memoria. Eliminar las dos clases de características originales. Ejecute la integración en la nueva clase de características. Coloque esa clase de característica en la cola de resultados.

A continuación, ejecute un bucle while externo. El bucle comienza con la cola de archivos shape y comprueba si la longitud es mayor que 1. A continuación, ejecuta la cola a través de los trabajadores. Si la cola de resultados tiene una longitud superior a 1, el bucle while ejecuta otra ejecución de procesamiento paralelo a través de los trabajadores hasta que la cola de resultados sea una clase de característica en memoria.

Por ejemplo, si empieza con 3500 shapefiles, su primera cola tendrá 3500 trabajos. La segunda tendrá 1750 trabajos. 875, 438, 219, 110, 55, 28, 14, 7, 4, 2, 1. Tu gran cuello de botella será la memoria. Si no tienes suficiente memoria (y te quedarás sin memoria en la creación de la primera cola de resultados si ese es el caso), entonces modifica tu algoritmo para fusionar más de 2 clases de características a la vez y luego integrar, lo que reducirá el tamaño de tu primera cola de resultados a cambio de un mayor tiempo de procesamiento. Opcionalmente, podría escribir archivos de salida y omitir el uso de clases de características en memoria. Esto le ralentizará considerablemente, pero superará el cuello de botella de la memoria.

Sólo después de haber realizado la fusión y la integración de todos los archivos shape, terminando con una sola clase de características, se realiza el buffer, la conversión de poli a raster y la reclasificación. De esta manera, estas tres operaciones se realizan una sola vez y se mantiene la geometría simple.

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