How to Make Raster Conditionals More Efficient

1114
1
01-10-2017 01:19 PM
AmyShaw
New Contributor II

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")‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
1 Reply
DanPatterson_Retired
MVP Emeritus

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

0 Kudos