Racionalización del código de Python para Big Data

34

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

  1. puntos de fusión
  2. Integrar puntos, de manera que cualquier punto dentro de 1 m uno del otro convertirse en un punto
  3. Crear capa de entidades, donde los puntos con z < 10 están seleccionados
  4. Puntos de amortiguación
  5. Resolución de polígono a ráster de 1m
  6. Reclasificar, donde 1 - 9 = 1; NoData = 0

Cada shapefile tiene aproximadamente 250,000 a 350,000 puntos que cubren ~ 5x7 km. Los datos de puntos utilizados como entradas representan las ubicaciones de los árboles. Cada punto (es decir, el árbol) tiene un valor "z" asociado que representa el radio de la corona y se utiliza en el proceso del búfer. Mi intención es usar la salida binaria final en un proceso separado para producir una trama que describa la cubierta del dosel.

Hice una prueba con cuatro shapefiles, produjo un raster de 700MB y tardé 35 minutos (procesador i5 y 8GB de RAM). Al ver que necesitaré ejecutar este proceso en 3500 shapefiles, agradecería cualquier consejo para simplificar el proceso (ver código adjunto). En términos generales, ¿cuál es la mejor manera de lidiar con el geoprocesamiento de big data? Más específicamente, ¿existen modificaciones en el código o en el flujo de trabajo que podrían ayudar a aumentar la eficiencia?

Editar :

Tiempo (% del total) para tareas de geoprocesamiento:

  • Combinar = 7.6%
  • Integrar = 7.1%
  • Característica a Lyr = 0
  • Buffer = 8.8%
  • Poly to Raster = 74.8%
  • Reclasificar = 1.6%

#Importarcpymoduleimportarcpy#Checkoutanynecessarylicensesarcpy.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")
    
pregunta Aaron 05.08.2012 - 01:04

2 respuestas

10

Algunos cambios de algoritmo que deberían ayudarte.

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

Tanto la combinación como la integración son costosas en cuanto a memoria, por lo que debes seguir eliminando las funciones a medida que incorporas clases de características e intentar realizar las combinaciones en un árbol binario para mantener el tamaño de las combinaciones y la integración. p.ej. para cuatro shapefiles usted combina dos shapefiles e integra; fusionar dos shapefiles más e integrar; fusionar las dos clases de entidad resultantes e integrarlas.

La cola de trabajos se inicia como una cola de referencias de shapefile. También tiene una cola de resultados para colocar los resultados en. El método run () para su trabajador de procesamiento paralelo realizará estas operaciones: Saque dos artículos de la cola. Si no se toma ningún elemento (la cola está vacía), termine el trabajador. Si se toma un elemento, colóquelo directamente en la cola de resultados.

Si se toman dos elementos, para cada elemento: si es un archivo de forma, seleccione para z < 10 y crea una clase de entidad en_memoria; de lo contrario, ya es una clase de entidad in_memory y omite el paso de selección. Combine las dos clases de entidad in_memory para crear una nueva clase de entidad in_memory. Eliminar las dos clases de entidad originales. Ejecutar integrar en la nueva clase de entidad. Coloque esa clase de entidad en la cola de resultados.

Luego ejecuta un bucle while externo. El bucle comienza con la cola del shapefile y comprueba una longitud mayor que 1. A continuación, ejecuta la cola a través de los trabajadores. Si la cola de resultados tiene una longitud mayor que 1, el bucle while ejecuta otra ejecución de procesamiento paralelo a través de los trabajadores hasta que la cola de resultados es 1 en clase de entidad de memoria.

por ejemplo Si comienza con 3500 shapefiles, su primera cola tendrá 3500 trabajos. El segundo tendrá 1750 puestos de trabajo. 875, 438, 219, 110, 55, 28, 14, 7, 4, 2, 1. Tu gran cuello de botella será la memoria. Si no tiene suficiente memoria (y se quedará sin memoria en la creación de la primera cola de resultados, si ese es el caso), modifique su algoritmo para combinar más de 2 clases de características a la vez y luego integre, lo que reducirá el tamaño de su primera cola de resultados a cambio de un mayor tiempo de procesamiento. Opcionalmente, puede escribir archivos de salida y omitir usando clases de entidad in_memory. Esto lo reducirá considerablemente, pero superará el cuello de botella de la memoria.

Solo después de realizar la combinación e integración en todos los shapefiles, que finaliza con una sola clase de entidad, realiza el búfer, poli a ráster y reclasifica. De esa manera, esas tres operaciones se realizan solo una vez y usted mantiene su geometría simple.

    
respondido por el blord-castillo 07.08.2012 - 16:35
14

Lo primero que haría es monitorear la utilización de los recursos de su sistema usando algo como Resource Monitor en Windows 7 o perfmon en Vista / XP para saber si usted es CPU -, memoria - o IO-bound .

Si tiene memoria o está enlazado a IO, es muy poco lo que puede hacer, pero puede actualizar el hardware, reducir el tamaño del problema o cambiar el enfoque por completo.

Si determina que está vinculado a la CPU, experimentaría con el módulo multiprocessing , o uno de los muchos paquetes de procesamiento paralelo disponibles en Python disponibles, para ver si puede usar más núcleos de CPU para acelerar su operaciones.

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

  1. Le permite dividir las entradas en conjuntos de trabajo más pequeños y luego combinar los resultados de una manera que tenga sentido,
  2. Agrega la menor cantidad de gastos generales (algunos es inevitable en comparación con el procesamiento en serie), y
  3. Le permite ajustar el tamaño del conjunto de trabajo para utilizar mejor los recursos del sistema para un rendimiento óptimo.

Puede usar el guión que creé en esta respuesta como punto de partida: ¿Código de Porting Avenue para producir sombras de construcción en ArcPy / Python para ArcGIS Desktop?

Vea también esta publicación del blog de geoprocesamiento ESRI sobre el tema: Multiprocesamiento de Python: enfoques y consideraciones

Creo que su caso será aún más desafiante debido a la naturaleza más "negra" de las herramientas que está utilizando, en lugar de las matrices de geometría de grano fino con las que estaba trabajando. Tal vez sea útil trabajar con NumPy .

También encontré un interesante material de lectura si querías ver más allá de arcpy:

respondido por el blah238 06.08.2012 - 21:23

Lea otras preguntas en las etiquetas