2015-03-24 2 views
0

Я пытаюсь сравнить NDVI calculations с использованием ArcPy (опытный) и NumPy (новичок), но работает в MemoryError, в строке, указанной в приведенном ниже скрипте.ArcPy & NumPy: MemoryError processing Landsat 8 image

Форма и тип массивов, созданных RasterToNumPyArray, являются (8191, 8101) и uint16. Это размер стандартного изображения Landsat 8.

Является ли этот необоснованный размер ожидаемым процессом? Проблема в том, что разделение способствует созданию dtype для размещения десятичных знаков (diff и sum успешно завершено)? Если да, могу ли я заставить целочисленный вывод каким-то образом?

import cProfile, numpy 
def arcpyNDVI(): 
    NIRras = arcpy.Raster("LC80460222013184LGN00_B5.TIF") 
    REDras = arcpy.Raster("LC80460222013184LGN00_B4.TIF") 
    NDVIap = (NIRras - arcpy.sa.Float(REDras))/ (NIRras + REDras) 
    NDVIap.save(r'C:/junk/ap_ras.tif') 
def numpyNDVI(): 
    NIRras = arcpy.Raster("LC80460222013184LGN00_B5.TIF") 
    NIRll = arcpy.Point(NIRras.extent.XMin,NIRras.extent.YMin) 
    NIRcs = NIRras.meanCellWidth 
    REDras = arcpy.Raster("LC80460222013184LGN00_B4.TIF") 
    arcpy.env.outputCoordinateSystem = NIRras.spatialReference 
    NIRnp = arcpy.RasterToNumPyArray(NIRras) 
    REDnp = arcpy.RasterToNumPyArray(REDras) 
    diff = NIRnp - REDnp 
    sum = NIRnp + REDnp 
    NDVInp = diff/sum # MEMORY ERROR HERE 
    NDVInpRas = arcpy.NumPyArrayToRaster(NDVInp,NIRll,NIRcs,NIRcs) 
    NDVInpRas.save(r'C:/junk/np_ras.tif') 
cProfile.runctx('arcpyNDVI()',None,locals()) 
cProfile.runctx('numpyNDVI()',None,locals()) 

update1: выше сценарий иногда идет к завершению (иногда дает MemoryError), но она выводит uint16, в то время как мне нужно десятичные. При изменении строки: NDVInp = diff/sum к: NDVInp = numpy.true_divide(diff,sum), я постоянно получаю:

Runtime error 
Traceback (most recent call last): 
    File "<string>", line 24, in <module> 
    File "C:\Anaconda\Lib\cProfile.py", line 49, in runctx 
    prof = prof.runctx(statement, globals, locals) 
    File "C:\Anaconda\Lib\cProfile.py", line 140, in runctx 
    exec cmd in globals, locals 
    File "<string>", line 1, in <module> 
    File "<string>", line 17, in numpyNDVI 
MemoryError 
+0

Это хорошая практика, чтобы всегда после полной отслеживающей в вашем вопросе –

+0

Вашего '(8191, 8101)' '' uint16' массивы diff' и 'sum' будет каждый принимать до ~ 130MB каждый. Автоматическое продвижение по плавающей позиции при выполнении 'diff/sum', поэтому результат должен быть ~ 130MB. Даже если они были добавлены в 'float64', вы все еще смотрите только на 500 МБ. Вы абсолютно уверены в размерах и типах этих массивов? –

+0

проверьте, можете ли вы очистить память между этапами ... это не файлы размером с размеру http://stackoverflow.com/questions/23977904/how-to-implement-garbage-collection-in-numpy, особенно, поскольку ArcGIS не работает Загрузите полную сумму в память –

ответ

0

Ответ, как представляется, чтобы освободить память, используя del операторы по всему, удаление переменных в кратчайшие момент. Если кто-то хочет прокомментировать, является ли это общей/лучшей практикой для numpy-скриптов (или Python, в общем), я все уши. Вот мой рабочий сценарий:

import numpy 
NIRras = arcpy.Raster("LC80460222013184LGN00_B5.TIF") 
NIRll = arcpy.Point(NIRras.extent.XMin,NIRras.extent.YMin) 
NIRcs = NIRras.meanCellWidth 
REDras = arcpy.Raster("LC80460222013184LGN00_B4.TIF") 
arcpy.env.outputCoordinateSystem = NIRras.spatialReference 
NIRnp = arcpy.RasterToNumPyArray(NIRras) 
del NIRras 
REDnp = arcpy.RasterToNumPyArray(REDras) 
del REDras 
diff = NIRnp - REDnp 
sum = NIRnp + REDnp 
del NIRnp, REDnp 
NDVInp = numpy.true_divide(diff,sum) # MEMORY ERROR HERE 
NDVInpRas = arcpy.NumPyArrayToRaster(NDVInp,NIRll,NIRcs,NIRcs) 
del NDVInp, NIRll, NIRcs 
NDVInpRas.save(r'C:/junk/np_ras.tif') 
del NDVInpRas 
Смежные вопросы