Mam tabelę z 8 kolumnami i ~ 16,7 miliona rekordów. Muszę uruchomić zestaw równań if-else na kolumnach. Napisałem skrypt za pomocą modułu UpdateCursor, ale po kilku milionach rekordów zabrakło mu pamięci. Zastanawiałem się, czy istnieje lepszy sposób na przetworzenie tych 16,7 miliona rekordów.
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"
AKTUALIZACJA # 1
Uruchomiłem ten sam skrypt na komputerze z 40 GB pamięci RAM (oryginalny komputer miał tylko 12 GB pamięci RAM). Pomyślnie ukończono po ~ 16 godzinach. Wydaje mi się, że 16 godzin to za długo, ale nigdy nie pracowałem z tak dużym zestawem danych, więc nie wiem, czego się spodziewać. Jedynym nowym dodatkiem do tego skryptu jest arcpy.env.parallelProcessingFactor = "100%"
. Próbuję dwóch sugerowanych metod (1) zrobienia 1 miliona rekordów partiami i (2) przy użyciu SearchCursor i zapisywania wyników do csv. Niedługo przedstawię sprawozdanie z postępów.
AKTUALIZACJA # 2
SearchCursor i aktualizacja CSV działały doskonale! Nie mam dokładnych czasów uruchomienia, zaktualizuję pocztę, gdy jutro będę w biurze, ale powiedziałbym, że przybliżony czas pracy wynosi ~ 5-6 minut, co jest dość imponujące. Nie spodziewałem się tego. Udostępniam mój nieoczyszczony kod wszelkie uwagi i ulepszenia są mile widziane:
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"
AKTUALIZACJA # 3 Ostatnia aktualizacja. Całkowity czas działania skryptu wynosi ~ 199,6 sekundy / 3,2 minuty.