Eu tenho uma tabela com 8 colunas e ~ 16,7 milhões de registros. Eu preciso executar um conjunto de equações if-else nas colunas. Eu escrevi um script usando o módulo UpdateCursor, mas depois de alguns milhões de registros, ele fica sem memória. Fiquei me perguntando se existe uma maneira melhor de processar esses 16,7 milhões 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"
ATUALIZAÇÃO # 1
Executei o mesmo script em um computador com 40 GB de RAM (o computador original tinha apenas 12 GB de RAM). Concluiu com sucesso após ~ 16 horas. Sinto que 16 horas são muito longas, mas nunca trabalhei com um conjunto de dados tão grande, então não sei o que esperar. A única nova adição a esse script é arcpy.env.parallelProcessingFactor = "100%"
. Estou tentando dois métodos sugeridos (1) fazendo 1 milhão de registros em lotes e (2) usando o SearchCursor e gravando saídas no CSV. Vou relatar o progresso em breve.
ATUALIZAÇÃO # 2
A atualização do SearchCursor e CSV funcionou de maneira brilhante! Eu não tenho os tempos de execução precisos, atualizarei a postagem quando estiver no escritório amanhã, mas diria que o tempo de execução aproximado é de aproximadamente 5-6 minutos, o que é bastante impressionante. Eu não estava esperando por isso. Estou compartilhando meu código não polido. Todos os comentários e melhorias são bem-vindos:
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"
ATUALIZAÇÃO # 3 Atualização final. O tempo total de execução do script é de ~ 199,6 segundos / 3,2 minutos.