Tengo una tabla con 8 columnas y ~ 16.7 millones de registros. Necesito ejecutar un conjunto de ecuaciones if-else en las columnas. He escrito un script usando el módulo UpdateCursor, pero después de algunos millones de registros se queda sin memoria. Me preguntaba si hay una mejor manera de procesar estos 16,7 millones de registros.
import arcpy
arcpy.TableToTable_conversion("combine_2013", "D:/mosaic.gdb", "combo_table")
c_table = "D:/mosaic.gdb/combo_table"
fields = ['dev_agg', 'herb_agg','forest_agg','wat_agg', 'cate_2']
start_time = time.time()
print "Script Started"
with arcpy.da.UpdateCursor(c_table, fields) as cursor:
for row in cursor:
# row's 0,1,2,3,4 = dev, herb, forest, water, category
#classficiation water = 1; herb = 2; dev = 3; forest = 4
if (row[3] >= 0 and row[3] > row[2]):
row[4] = 1
elif (row[2] >= 0 and row[2] > row[3]):
row[4] = 4
elif (row[1] > 180):
row[4] = 2
elif (row[0] > 1):
row[4] = 3
cursor.updateRow(row)
end_time = time.time() - start_time
print "Script Complete - " + str(end_time) + " seconds"
ACTUALIZACIÓN # 1
Ejecuté el mismo script en una computadora con 40 gb de RAM (la computadora original tenía solo 12 gb de RAM). Se completó con éxito después de ~ 16 horas. Siento que 16 horas son demasiado largas, pero nunca he trabajado con un conjunto de datos tan grande, así que no sé qué esperar. La única adición nueva a este script es arcpy.env.parallelProcessingFactor = "100%"
. Estoy probando dos métodos sugeridos (1) hacer 1 millón de registros en lotes y (2) usar SearchCursor y escribir resultados en csv. Informaré sobre el progreso en breve.
ACTUALIZACIÓN # 2
¡La actualización de SearchCursor y CSV funcionó de manera brillante! No tengo los tiempos de ejecución precisos, actualizaré la publicación cuando esté en la oficina mañana, pero diría que el tiempo de ejecución aproximado es de ~ 5-6 minutos, lo cual es bastante impresionante. No lo esperaba. Estoy compartiendo mi código sin pulir, cualquier comentario y mejora son bienvenidos:
import arcpy, csv, time
from arcpy import env
arcpy.env.parallelProcessingFactor = "100%"
arcpy.TableToTable_conversion("D:/mosaic.gdb/combine_2013", "D:/mosaic.gdb", "combo_table")
arcpy.AddField_management("D:/mosaic.gdb/combo_table","category","SHORT")
# Table
c_table = "D:/mosaic.gdb/combo_table"
fields = ['wat_agg', 'dev_agg', 'herb_agg','forest_agg','category', 'OBJECTID']
# CSV
c_csv = open("D:/combine.csv", "w")
c_writer = csv.writer(c_csv, delimiter= ';',lineterminator='\n')
c_writer.writerow (['OID', 'CATEGORY'])
c_reader = csv.reader(c_csv)
start_time = time.time()
with arcpy.da.SearchCursor(c_table, fields) as cursor:
for row in cursor:
#skip file headers
if c_reader.line_num == 1:
continue
# row's 0,1,2,3,4,5 = water, dev, herb, forest, category, oid
#classficiation water = 1; dev = 2; herb = 3; ; forest = 4
if (row[0] >= 0 and row[0] > row[3]):
c_writer.writerow([row[5], 1])
elif (row[1] > 1):
c_writer.writerow([row[5], 2])
elif (row[2] > 180):
c_writer.writerow([row[5], 3])
elif (row[3] >= 0 and row[3] > row[0]):
c_writer.writerow([row[5], 4])
c_csv.close()
end_time = time.time() - start_time
print str(end_time) + " - Seconds"
ACTUALIZACIÓN # 3 Actualización final. El tiempo de ejecución total para el script es de ~ 199.6 segundos / 3.2 minutos.