I have a piece of working python code that I am looking to make more efficient.
The code is trying to model vegetation change based on 4 rasters containing data on potential evapotranspiration, climate moisture index, precipitation, and summer precipitation.
I also have a base vegetation raster that will have its values updated based on a set of conditions depending on values of the 4 rasters above at each cell.
I have no idea how to do this without going through the rasters cell by cell because I have to know the cell values for all layers in order for the conditions to work on the cells of the vegetation layer.
What is a better way of doing this?
Code below:
import arcpy
import numpy
inRasPE = arcpy.Raster("C:/VegModel/CCSSRawData.gdb/pe100Year2")
inRasCMI = arcpy.Raster("C:/VegModel/CCSSRawData.gdb/cmi100Year2")
inRasPCP = arcpy.Raster("C:/VegModel/CCSSRawData.gdb/pcp100Year2")
inRasSPP = arcpy.Raster("C:/VegModel/CCSSRawData.gdb/spp100Year2")
#inRasVeg = arcpy.Raster("C:/VegModel/CCSSRawData.gdb/vegnormrs100") #To be used the first time.
inRasVeg = arcpy.Raster("C:/VegModel/CCSSRawData.gdb/veg100Year1Revise3")
lowerLeft = arcpy.Point(inRasVeg.extent.XMin, inRasVeg.extent.YMin)
cellSize = inRasVeg.meanCellWidth
inArrayPE = arcpy.RasterToNumPyArray(inRasPE)
inArrayCMI = arcpy.RasterToNumPyArray(inRasCMI)
inArrayPCP = arcpy.RasterToNumPyArray(inRasPCP)
inArraySPP = arcpy.RasterToNumPyArray(inRasSPP)
inArrayVeg = arcpy.RasterToNumPyArray(inRasVeg, nodata_to_value = 0)
rasHeight, rasWidth = inArrayVeg.shape
for i in range(0, rasHeight):
for j in range(0, rasWidth):
value1 = inArrayPE[i, j]
value2 = inArrayVeg[i, j]
value3 = inArrayCMI[i, j]
if value1 <= 760:
if value2 == 11 and value3 < 0:
value2 = 21
inArrayVeg[i, j] = value2
elif value2 == 12 and value3 < 0:
value2 = 22
inArrayVeg[i, j] = value2
elif value2 == 13 and value3 < 0:
value2 = 23
inArrayVeg[i, j] = value2
elif value2 == 14 and value3 < 0:
value2 = 24
inArrayVeg[i, j] = value2
elif value2 == 15 and value3 < 0:
value2 = 25
inArrayVeg[i, j] = value2
elif value2 == 16 and value3 < 0:
value2 = 26
inArrayVeg[i, j] = value2
elif value2 == 21 and value3 < -150:
value2 = 41
inArrayVeg[i, j] = value2
elif value2 == 22 and value3 < -150:
value2 = 42
inArrayVeg[i, j] = value2
elif value2 == 23 and value3 < -150:
value2 = 43
inArrayVeg[i, j] = value2
elif value2 == 24 and value3 < -150:
value2 = 44
inArrayVeg[i, j] = value2
elif value2 == 25 and value3 < -40:
value2 = 26
inArrayVeg[i, j] = value2
elif value2 == 26 and value3 < -80:
value2 = 24
inArrayVeg[i, j] = value2
elif value2 == 31 and value3 < -260:
value2 = 41
inArrayVeg[i, j] = value2
elif value2 == 32 and value3 < -260:
value2 = 42
inArrayVeg[i, j] = value2
elif value2 == 33 and value3 < -260:
value2 = 43
inArrayVeg[i, j] = value2
elif value2 == 34 and value3 < -260:
value2 = 44
inArrayVeg[i, j] = value2
elif value2 == 35 and value3 < -220:
value2 = 36
inArrayVeg[i, j] = value2
elif value2 == 36 and value3 < -250:
value2 = 34
inArrayVeg[i, j] = value2
elif value2 == 41 and value3 < -300:
value2 = 51
inArrayVeg[i, j] = value2
elif value2 == 42 and value3 < -300:
value2 = 52
inArrayVeg[i, j] = value2
elif value2 == 43 and value3 < -300:
value2 = 53
inArrayVeg[i, j] = value2
elif value2 == 44 and value3 < -300:
value2 = 54
inArrayVeg[i, j] = value2
elif value2 == 51 and value3 < -400:
value2 = 56
inArrayVeg[i, j] = value2
elif value2 == 53 and value3 < -440:
value2 = 52
inArrayVeg[i, j] = value2
elif value2 == 54 and value3 < -320:
value2 = 53
inArrayVeg[i, j] = value2
elif value2 == 56 and value3 < -440:
value2 = 57
inArrayVeg[i, j] = value2
elif value1 > 760:
value4 = inArrayPCP[i, j]
value5 = inArraySPP[i, j]
sixtyThree = -37.298 + (0.027 * value4) + (0.004 * value1) + (70.895 * value5)
sixtyFour = -29.53 + (0.001 * value4) + (0.007 * value1) + (79.182 * value5)
sixtyFive = -73.987 + (0.002 * value4) + (0.04 * value1) + (114.753 * value5)
sixtySix = -67.219 + (0.031 * value4) + (0.017 * value1) + (121.6 * value5)
sixtySeven = -190.354 + (0.102 * value4) + (0.023 * value1) + (310.128 * value5)
seventyFour = -252.386 + (0.163 * value4) + (0.01 * value1) + (399.599 * value5)
isMax = sixtyThree
if sixtyFour > isMax:
isMax = sixtyFour
if sixtyFive > isMax:
isMax = sixtyFive
if sixtySix > isMax:
isMax = sixtySix
if sixtySeven > isMax:
isMax = sixtySeven
if seventyFour > isMax:
isMax = seventyFour
if value2 == 52 or value2 == 53 or value2 == 54 or value2 == 63 or value2 == 64 or value2 == 65 or value2 == 66 or value2 == 67 or value2 == 74:
if isMax == sixtyThree:
value2 = 63
inArrayVeg[i, j] = value2
elif isMax == sixtyFour:
value2 = 64
inArrayVeg[i,j] = value2
elif isMax == sixtyFive:
value2 = 65
inArrayVeg[i, j] = value2
elif isMax == sixtySix:
value2 = 66
inArrayVeg[i, j] = value2
elif isMax == sixtySeven:
value2 = 67
inArrayVeg[i, j] = value2
elif isMax == seventyFour:
value2 = 74
inArrayVeg[i, j] = value2
elif value2 == 11 and value3 < 0:
value2 = 21
inArrayVeg[i, j] = value2
elif value2 == 12 and value3 < 0:
value2 = 22
inArrayVeg[i, j] = value2
elif value2 == 13 and value3 < 0:
value2 = 23
inArrayVeg[i, j] = value2
elif value2 == 14 and value3 < 0:
value2 = 24
inArrayVeg[i, j] = value2
elif value2 == 15 and value3 < 0:
value2 = 25
inArrayVeg[i, j] = value2
elif value2 == 16 and value3 < 0:
value2 = 26
inArrayVeg[i, j] = value2
elif value2 == 21 and value3 < -150:
value2 = 41
inArrayVeg[i, j] = value2
elif value2 == 22 and value3 < -150:
value2 = 42
inArrayVeg[i, j] = value2
elif value2 == 23 and value3 < -150:
value2 = 43
inArrayVeg[i, j] = value2
elif value2 == 24 and value3 < -150:
value2 = 44
inArrayVeg[i, j] = value2
elif value2 == 25 and value3 < -40:
value2 = 26
inArrayVeg[i, j] = value2
elif value2 == 26 and value3 < -80:
value2 = 24
inArrayVeg[i, j] = value2
elif value2 == 31 and value3 < -260:
value2 = 41
inArrayVeg[i, j] = value2
elif value2 == 32 and value3 < -260:
value2 = 42
inArrayVeg[i, j] = value2
elif value2 == 33 and value3 < -260:
value2 = 43
inArrayVeg[i, j] = value2
elif value2 == 34 and value3 < -260:
value2 = 44
inArrayVeg[i, j] = value2
elif value2 == 35 and value3 < -220:
value2 = 36
inArrayVeg[i, j] = value2
elif value2 == 36 and value3 < -250:
value2 = 34
inArrayVeg[i, j] = value2
elif value2 == 41 and value3 < -300:
value2 = 51
inArrayVeg[i, j] = value2
elif value2 == 42 and value3 < -300:
value2 = 52
inArrayVeg[i, j] = value2
elif value2 == 43 and value3 < -300:
value2 = 53
inArrayVeg[i, j] = value2
elif value2 == 44 and value3 < -300:
value2 = 54
inArrayVeg[i, j] = value2
elif value2 == 51 and value3 < -400:
value2 = 56
inArrayVeg[i, j] = value2
elif value2 == 56 and value3 < -440:
value2 = 57
inArrayVeg[i, j] = value2
newRaster = arcpy.NumPyArrayToRaster(inArrayVeg, lowerLeft, cellSize, value_to_nodata = 0)
newRaster.save("C:/VegModel/Revise.gdb/veg100Year2Revise3")
Come up with a list of your conditions in a matrix form
In the interim, work through the logic in this example of how to work with conditional statements in numpy. I have presented this as verbosely as possible using np functions rather than shortcuts. Once you understand the workflow I can show the shortcuts...
>>> a = np.arange(36).reshape(6,6)
>>> b = np.where(a % 2 == 0, a, np.random.randint(36))
>>> c = np.where(a < 18, a, np.random.randint(36))
>>> a
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35]])
>>> b
array([[ 0, 34, 2, 34, 4, 34],
[ 6, 34, 8, 34, 10, 34],
[12, 34, 14, 34, 16, 34],
[18, 34, 20, 34, 22, 34],
[24, 34, 26, 34, 28, 34],
[30, 34, 32, 34, 34, 34]])
>>> c
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[27, 27, 27, 27, 27, 27],
[27, 27, 27, 27, 27, 27],
[27, 27, 27, 27, 27, 27]])
>>> d = np.logical_and(a > 15, b ==34)
>>> d
array([[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1],
[0, 1, 0, 1, 0, 1],
[0, 1, 0, 1, 0, 1],
[0, 1, 0, 1, 1, 1]], dtype=bool)
>>> e = np.logical_or(c > 15, b !=34)
>>> e
array([[1, 0, 1, 0, 1, 0],
[1, 0, 1, 0, 1, 0],
[1, 0, 1, 0, 1, 1],
[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1]], dtype=bool)
>>>
>>> final = np.where(d+e==0,5,np.where(d+e==1,6,7))
>>> final
array([[6, 5, 6, 5, 6, 5],
[6, 5, 6, 5, 6, 5],
[6, 5, 6, 5, 6, 6],
[6, 6, 6, 6, 6, 6],
[6, 6, 6, 6, 6, 6],
[6, 6, 6, 6, 6, 6]])
Good luck