Select to view content in your preferred language

How to use Min/Max values of raster in Python script

9257
7
Jump to solution
07-27-2015 08:30 AM
KarolinaKorzeniowska
Deactivated User

I would like to use Min/Max values of my raster data in Python script. However, I cannot find an information how to implement these values properly in script. My script is as follow:

#Get the geoprocessing result object

elevMINResult = arcpy.GetRasterProperties_management("6", "MINIMUM")

elevMAXResult = arcpy.GetRasterProperties_management("6", "MAXIMUM")

#Get the elevation min/max value from geoprocessing result object

elevMin = elevMINResult.getOutput(0)

elevMax = elevMAXResult.getOutput(0)

# Set local variables

inRaster1 = Raster("6")

# Execute Minus

outMinus = ((inRaster1 - (elevMin)))/((elevMax) - (elevMin))

# Save the output

outMinus.save("C:/out")

After running the script, I have the following error:

ERROR 000732: Dataset -1.79666268825531 does not exist or is not supported. -1.79666268825531 is elevMin in my data

Does anyone know how to implement Min/Max values to Python script?

0 Kudos
1 Solution

Accepted Solutions
JakeSkinner
Esri Esteemed Contributor

Hi Karolina,

You will also need to call the Minus and Divide functions.  Ex:

import arcpy
arcpy.CheckOutExtension("Spatial")
from arcpy.sa import *

inRaster1 = r"C:\DATA\RASTER\DEM\example"

elevMINResult = arcpy.GetRasterProperties_management(inRaster1, "MINIMUM")
elevMAXResult = arcpy.GetRasterProperties_management(inRaster1, "MAXIMUM")

elevMin = float(elevMINResult.getOutput(0))
elevMax = float(elevMAXResult.getOutput(0))

divideValue = (elevMax - elevMin)

outMinus = Minus(inRaster1, elevMin)
outDivide = Divide(outMinus, divideValue)

outDivide.save(r"C:\temp\output.tif")

View solution in original post

7 Replies
DarrenWiens2
MVP Honored Contributor

In addition to Jake's answer (now deleted), here's why you need to cast to float.

elevMin = float(elevMINResult.getOutput(0))

getOutput(0) returns either a record set, string, or layer. In your case it returns a string.

>>> print type(elevMINResult.getOutput(0))
<type 'unicode'>

In turn, your map algebra expression interprets the value as a string, or raster name.

0 Kudos
JakeSkinner
Esri Esteemed Contributor

Hi Karolina,

You will also need to call the Minus and Divide functions.  Ex:

import arcpy
arcpy.CheckOutExtension("Spatial")
from arcpy.sa import *

inRaster1 = r"C:\DATA\RASTER\DEM\example"

elevMINResult = arcpy.GetRasterProperties_management(inRaster1, "MINIMUM")
elevMAXResult = arcpy.GetRasterProperties_management(inRaster1, "MAXIMUM")

elevMin = float(elevMINResult.getOutput(0))
elevMax = float(elevMAXResult.getOutput(0))

divideValue = (elevMax - elevMin)

outMinus = Minus(inRaster1, elevMin)
outDivide = Divide(outMinus, divideValue)

outDivide.save(r"C:\temp\output.tif")
DarrenWiens2
MVP Honored Contributor

Can you explain this further? I was under the impression that once a raster was included in the expression, it is interpreted as map algebra. For example, similar to the original post:

inRaster1 = arcpy.Raster(r"C:\DATA\RASTER\DEM\example")
elevMINResult = arcpy.GetRasterProperties_management(inRaster1, "MINIMUM") 
elevMin = float(elevMINResult.getOutput(0))  
outMinus = inRaster1 - elevMin

I believe this should work, producing a new raster minus the constant, elevMin. However, I'm not clear on how Python actually decides to apply a map algebra expression on what may appear to be a normal expression.

0 Kudos
JakeSkinner
Esri Esteemed Contributor

You can include a raster in an expression, but you need to specify the raster first, as Xander Bakker mentions, using a raster object.

For example, the following will produce the error 'TypeError: unsupported operand type(s) for -: 'str' and 'float'':

inRaster1 = ("int_example1")

elevMINResult = arcpy.GetRasterProperties_management(r"C:\DATA\RASTER\DEM\int_example1", "MINIMUM")
elevMAXResult = arcpy.GetRasterProperties_management(r"C:\DATA\RASTER\DEM\int_example1", "MAXIMUM")

elevMin = float(elevMINResult.getOutput(0))
elevMax = float(elevMAXResult.getOutput(0))

outMinus = ((inRaster1 - (elevMin)))/((elevMax) - (elevMin))
outMinus.save(r"C:\temp\python\output.tif")

However, the following will work:

inRaster1 = arcpy.Raster("int_example1")

elevMINResult = arcpy.GetRasterProperties_management(r"C:\DATA\RASTER\DEM\int_example1", "MINIMUM")
elevMAXResult = arcpy.GetRasterProperties_management(r"C:\DATA\RASTER\DEM\int_example1", "MAXIMUM")

elevMin = float(elevMINResult.getOutput(0))
elevMax = float(elevMAXResult.getOutput(0))

outMinus = ((inRaster1 - (elevMin)))/((elevMax) - (elevMin))
outMinus.save(r"C:\temp\python\output.tif")
0 Kudos
XanderBakker
Esri Esteemed Contributor

Suppose you have a raster called "DEM" (in your TOC), you could use the maximum and minimum properties directly like this:

import arcpy
dem = Raster("DEM")
result = (dem - dem.minimum) / (dem.maximum - dem.minimum)

This will generate a raster with values ranging from 0 (minimum) to 1 (maximum).

What does the "6" stand for in your code? Is this the name of a raster in your TOC or a value that you want to use as constant?

KarolinaKorzeniowska
Deactivated User

Thank you for all the answers. I tried to implement both solution, and both works fine.

"6" in my code is the result map, like 1, 2, 3, 4, 5. I am trying to implement saving the intermediate results in the memory, but sometimes I have errors, so for now it is 1, 2, 3, 4...

I have one more question, related to Jake's code. Once he is writing subtraction using minus and once using comma. What is more correct. It depend on the input data, or something else?

  1. divideValue = (elevMax - elevMin) 
  2.  
  3. outMinus = Minus(inRaster1, elevMin)

And also one more question regarding the results. At first I built my script using Model Builder. In model builder by taking min and max value of raster I have never received 0 (zero) as the smallest value but something like 2.5569548399738e-015 or similar. Using Jake's and your code for Python the smallest value is 0 (zero). Is there something wrong with model Builder?

0 Kudos
curtvprice
MVP Esteemed Contributor

Karolina, up-thread this was discussed some. Esri has implemented their raster tools so they can work easily in Python syntax, so what the "-" does depends on the input. For example this python code will set result to the integer value 1, and result2 to a float (float - integer => integer). So the result depends on the inputs.

x = 1
y = 2
result = y - x
y = 2.0
result2 = y - x

Similarly if you subtract a raster object from an integer, you'll get a raster out.

The map algebra syntax has the advantage that it is easy to read, write, and debug, and you can create complex expressions that can nest your processing very efficiently -- instead of running a bunch of tools one at a time.

from arcpy.sa import *
x = 1
y = Raster("y.tif") # convert a text path to a raster object
# the following three lines are entirely equivalent (they do the same thing)
result3 = y - x 
result3 = Subtract(y, x)
result3 = Subtract("y.tif", x)
result3.save("z.tif")

Hopefully my little discussion above will help you make more sense of the help pages on arcpy map algebra.