Ho una tabella con 8 colonne e ~ 16,7 milioni di record. Devo eseguire una serie di equazioni if-else sulle colonne. Ho scritto uno script usando il modulo UpdateCursor, ma dopo qualche milione di dischi ha esaurito la memoria. Mi chiedevo se esiste un modo migliore per elaborare questi 16,7 milioni di record.
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"
AGGIORNAMENTO # 1
Ho eseguito lo stesso script su un computer con 40 GB di RAM (il computer originale aveva solo 12 GB di RAM). Si è completato con successo dopo ~ 16 ore. Sento che 16 ore sono troppo lunghe, ma non ho mai lavorato con un set di dati così grande, quindi non so cosa aspettarmi. L'unica nuova aggiunta a questo script è arcpy.env.parallelProcessingFactor = "100%"
. Sto provando due metodi suggeriti (1) facendo 1 milione di record in batch e (2) usando SearchCursor e scrivendo output in csv. Riferirò sui progressi a breve.
AGGIORNAMENTO # 2
L'aggiornamento di SearchCursor e CSV ha funzionato alla grande! Non ho i tempi di esecuzione precisi, aggiornerò il post quando sarò in carica domani, ma direi che il tempo di esecuzione approssimativo è di ~ 5-6 minuti, il che è piuttosto impressionante. Non me lo aspettavo. Condivido il mio codice non lucidato e sono ben accetti commenti e miglioramenti:
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"
UPDATE # 3 Aggiornamento finale. Il tempo di esecuzione totale per lo script è ~ 199,6 secondi / 3,2 minuti.