我正在尝试使用ArcPy(有经验的)和NumPy(新手)比较NDVI calculations,但是在下面的脚本中指示的行中运行MemoryError
。
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)
答案似乎是使用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