2 votos

Combinando python (parallel) multiprocessing toolbox con arcpy

Estoy intentando reducir el tiempo de procesamiento de arcpy utilizando la caja de herramientas de multiprocesamiento de python. Usando el ejemplo de http://wltrimbl.github.io/2014-06-10-spelman/intermediate/python/04-multiprocessing.html como directriz.

Básicamente, estoy tratando de seleccionar todas las pistas (características de punto) con un trackID específico (en el campo 'pista'), darle un buffer y extraer todas las características de carretera dentro de ese buffer como preprocesamiento para otro script. Pero el conjunto de datos es tan grande que me llevaría una semana ejecutarlo.

Ahora tengo el siguiente código, pero estoy teniendo un problema con el programa se ejecuta normalmente, pero no la salida de los archivos en Tracks.gdb. ¿Alguien tiene algún consejo?

import arcpy
from arcpy import env
import multiprocessing
def MyFunction(i):
    TrackFeatureOut = "C:\tryingOut\Tracks.gdb\Track_" + str(i)
    RoadFeatureOut = "C:\tryingOut\Tracks.gdb\Road_" + str(i)
    if not (RoadFeatureOut in featureclasses):
        BufferFeatureOut = "C:\tryingOut\Temporary.gdb\Buffer_" + str(i)
        Query = "track =" + str(i)

        arcpy.Select_analysis("C:\tryingOut\Input.gdb\Tracks", TrackFeatureOut, Query)

        arcpy.Buffer_analysis(TrackFeatureOut, BufferFeatureOut, "100 Meters")

        arcpy.Clip_analysis("C:\tryingOut\Input.gdb\Roads", BufferFeatureOut, RoadFeatureOut)

if __name__ == '__main__':
    global featureclasses
    env.workspace = "C:\tryingOut\Tracks.gdb"
    featureclasses = arcpy.ListFeatureClasses()

    # Getting all unique track numbers
    Track = set([])
    cursor = arcpy.da.SearchCursor("C:\tryingOut\Input.gdb\Tracks",["track"],sql_clause=(None, 'ORDER BY track' ))
    for row in cursor:
        Track.add(row[0])

    # Trying to apply multiprocessing
    pool = multiprocessing.Pool(multiprocessing.cpu_count())
    for i in Track:
        if Counter % 1000 == 0:
            print "Counter = ", Counter, "Current Track = ",i
        Counter += 1    
        pool.apply_async(MyFunction, i)

0voto

Rob Puntos 1

Hay dos mejoras que debería haber hecho aquí:

En primer lugar, está la función arcpy arcpy.SplitByAttributes_analysis(), que (en mi experiencia) funciona más eficientemente que la función select.

En segundo lugar, mi forma de multiprocesamiento no funcionaba, o al menos encontré una forma que sí funcionaba. Conseguí escribir una función corta que debería tomar cualquier función y lista iterable como argumentos de entrada y multiprocesarla al número de núcleos disponibles:

def multiprocessingfunc(Func, List):
    Count = 0
    while Count < len(List):
        if len(multiprocessing.active_children()) < multiprocessing.cpu_count():
            p = multiprocessing.Process(target=Func, args=(List[Count],)
            p.start()
            Count += 1

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