Ich habe eine Tabelle mit 8 Spalten und ~ 16,7 Millionen Datensätzen. Ich muss eine Reihe von if-else-Gleichungen für die Spalten ausführen. Ich habe ein Skript mit dem UpdateCursor-Modul geschrieben, aber nach einigen Millionen Datensätzen ist der Speicher voll. Ich habe mich gefragt, ob es einen besseren Weg gibt, diese 16,7 Millionen Datensätze zu verarbeiten.
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"
UPDATE # 1
Ich habe das gleiche Skript auf einem Computer mit 40 GB RAM ausgeführt (der ursprüngliche Computer hatte nur 12 GB RAM). Es wurde nach ca. 16 Stunden erfolgreich abgeschlossen. Ich halte 16 Stunden für zu lang, aber ich habe noch nie mit einem so großen Datensatz gearbeitet, dass ich nicht weiß, was mich erwartet. Die einzige Neuerung in diesem Skript ist arcpy.env.parallelProcessingFactor = "100%"
. Ich versuche zwei vorgeschlagene Methoden (1) 1 Million Datensätze in Stapeln zu erstellen und (2) SearchCursor zu verwenden und Ausgaben in csv zu schreiben. Ich werde in Kürze über die Fortschritte berichten.
UPDATE # 2
Das SearchCursor- und CSV-Update hat hervorragend funktioniert! Ich habe nicht die genauen Laufzeiten, ich werde den Post aktualisieren, wenn ich morgen im Büro bin, aber ich würde sagen, die ungefähre Laufzeit beträgt ~ 5-6 Minuten, was ziemlich beeindruckend ist. Ich habe es nicht erwartet. Ich teile meinen unpolierten Code, Kommentare und Verbesserungen sind willkommen:
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 Letztes Update. Die Gesamtlaufzeit für das Skript beträgt ~ 199,6 Sekunden / 3,2 Minuten.