Estoy tratando de utilizar el multiprocesamiento para ayudarme a ejecutar una herramienta que recorte una característica y sume un atributo en ella. La herramienta necesita iterar a través de unas 24.000 filas de una featureclass mientras hace esto. Puedo ejecutarla sin multiprocesamiento, pero tarda mucho tiempo (más de 20 horas). Por ello, estoy intentando utilizar el multiprocesamiento para que se ejecute más rápido, ya que es probable que tenga que volver a utilizar este tipo de herramienta con conjuntos de datos más grandes. Sin embargo, cuando lo ejecuto, se ejecuta y termina, pero no hay salida y cuando miro los shapefiles creados durante el mismo, el updatecursor no se ha ejecutado en ellos. Espero que alguien pueda ayudarme a codificar mejor para que funcione.
import arcpy
import os
import multiprocessing
#this toolbox is full of tools I've made, I use one of them later
arcpy.ImportToolbox(
r'C:\Users\joe.chestnut\Documents\PythonScripts\JoesTools.pyt')
#geodatabase that my files are all in
arcpy.env.workspace = r"D:\Joe.Chestnut\Dallas\Dallas.gdb"
#This is the actual function that I need to run.
def ClipCount(stuffpassed):
#ranges are based on the oid. they stratify the data so that it can be multiprocessed.
ranges = stuffpassed[0]
#this is my file with about 25,000 polygon features (service areas for census blocks in Dallas
inputfile = stuffpassed[1]
#This file is the census blocks in dallas, and has some job data in it
inputfile2 = stuffpassed[2]
print(ranges)
print"RunningClipCount)"
arcpy.env.workspace =r"D:\Joe.Chestnut\Dallas"
i, j = ranges[0], ranges[1]
#This copies my file into a folder and creates 4 different copies of it, for the four different processors to run on
infile = arcpy.management.CopyFeatures(inputfile, 'layer{0}'.format(i), """OID>= {0} AND OID <= {1}""".format(i, j))
print(infile)
#makes a layer out of my census blocks so that they can be geoprocessed
cliplayer = arcpy.management.MakeFeatureLayer(inputfile2, "clipmedallas")
print(cliplayer)
#this cursor runs through each of the rows of the service areas file, and for each one will clip
#the census block file. Using a searchcursor on the clipped output, it will then sum the values in the 'newpop' field
#the summed values are then written into the 'jobcount' field of the service area file using the update cursor.
with arcpy.da.UpdateCursor(infile, ["Name", "jobcount"]) as cursor:
print "updatecursorrunning"
for row in cursor:
value = row[0]
field = "Name"
exp = field+"='" + value + "'"
infile3 = arcpy.MakeFeatureLayer_management(infile, "infile3")
rowselect = arcpy.SelectLayerByAttribute_management(infile3, "NEW_SELECTION", exp)
clipedlyr = arcpy.LEHDClipper(cliplayer, rowselect, "in_memory", "in_memory\clipedlyr")
with arcpy.da.SearchCursor(clipedlyr, "newpop") as newcursor:
stationpop = []
for srow in newcursor:
value = float(srow[0])
stationpop.append(value)
print(stationpop)
totalpop= 0
for num in stationpop:
totalpop = totalpop + num
print(totalpop)
row[1] = totalpop
cursor.updateRow(row)
arcpy.Delete_management(clipedlyr)
#This is the main function where I give the inputs for the ClipCount and then actually run the multiprocessing module.
def main():
ranges = [[1, 6000], [6001, 12000], [12001, 18000], [18001, 24000]]
inputfile =r'D:\Joe.Chestnut\Dallas\Dallas.gdb\gtfs\BlockAccess'
inputfile2 = r'D:\Joe.Chestnut\Dallas\Dallas.gdb\gtfs\Dallas_1clip'
stuffpassed = [ranges, inputfile, inputfile2]
pool = multiprocessing.Pool(processes=4, initializer=None, maxtasksperchild = 1)
result = pool.map_async(ClipCount, stuffpassed)
pool.close()
pool.join()
print result
if __name__ == '__main__':
main()
Cuando ejecuto esto, obtengo el siguiente resultado:
<multiprocessing.pool.MapResult object at 0x1467CAD0>
También crea cuatro copias del archivo de entrada como shapefiles. Sin embargo, aparte de esto, no creo saber si está haciendo algo.
¿Alguien sabe qué estoy haciendo mal?
¿Cómo consigo que el cursor de actualización se ejecute con el multiprocesamiento?