raster calculation in python

2938
8
Jump to solution
06-10-2014 06:19 PM
Leo_KrisPalao
New Contributor II
Hi ArcGIS Python experts,

I am working on automating my workflow for a project.  For now I am testing my script for only five rasters, then scale-up my analysis if the script will work okay. Once the code is already running, I will incorporate it in another code that I am setting up. I want to get the percentage of each cell using raster calculator. I got the initial code from another thread.

The equation that I am trying to execute is (raster1) / (a specified value) * 100 # computing for percentage

The workflow looks like:
RE_suitable_dek001 / 11.2 * 100
RE_suitable_dek002 / 14.9 * 100
RE_suitable_dek003 / 9.4 * 100
RE_suitable_dek004 / 10.4 * 100
RE_suitable_dek005 / 12.4 * 100

Some details:
Software: ArcGIS 10.2
OS: Windows 7 Prof 64 bit
Python console: PythonWin

import arcpy, os, sys from arcpy import env from arcpy.sa import * arcpy.env.overwriteOutput = True arcpy.CheckOutExtension("Spatial") arcpy.env.workspace = r'E:\Test_awd\awd_pct'  # Raster workspace raster_ws = r'E:\Test_awd\awd_pct'  # Getting the list of raster dataset arcpy.env.workspace = raster_ws rasters = [os.path.join(raster_ws, r) for r in arcpy.ListRasters()]  #Output workspace raster_ow = r'E:\Test_awd\awd_pct'  # Get dictionary (raster1:value, ..., raster5:value) rastVal = {"RE_suitable_dek001":11.2,"RE_suitable_dek002":14.9, "RE_suitable_dek003":9.4, "RE_suitable_dek004":10.4, "RE_suitable_dek005":12.4}  # Raster map algebra for rast in rastVal: # Iterate to all raster in the directory    outRaster = os.path.join(raster_ow, os.path.basename(rast)) # output path and filename of my raster    if rast in rastVal: # iterate my raster if in the dictionary       outRaster = rasters / rastVal[rast] * 100 # the equation that I want to execute...(raster1/11.2)*100       outRaster.save(outRaster + "pct") # output raster with pct (percentage) suffix    else:       print "ERROR: No matching entry in raster value look up dictionary!"



This is the error that I am getting:
Traceback (most recent call last):
  File "C:\Python27\ArcGIS10.2\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 326, in RunScript
    exec codeObject in __main__.__dict__
  File "E:\Python_scripts\ArcGIS\AWD_pct_v2.py", line 25, in <module>
    outRaster = rasters / rastVal[rast] * 100 # the equation that I want to execute...(raster1/11.2)*100
TypeError: unsupported operand type(s) for /: 'list' and 'float'

Thanks,
-Leo
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
Luke_Pinner
MVP Regular Contributor
Change your for loop from
for rast in rastVal:

To:
for rast in rasters:

Then this should work:
outRaster = Raster(rast) / rastVal[rast] * 100

View solution in original post

0 Kudos
8 Replies
IanMurray
Frequent Contributor
Hi Leo,

From the error code, its pretty clear what the problem is in your code.

Line 25
outRaster = rasters / rastVal[rast] * 100
TypeError: unsupported operand type(s) for /: 'list' and 'float'


From your code I'm not sure exactly what you are trying to do, but you are dividing a list by a float and that throws a type error, since rasters = [os.path.join(raster_ws, r) for r in arcpy.ListRasters()], so your variable rasters is a list. 

Depending on what you are trying to do, you will probably need to loop through your rasters list to get the actual raster out of it.

If you could make it a bit more clear what you are trying to do, it would be a little easier to help you out, but thats why its throwing an error.

Edit: Read your post a bit more carefully, if you just need the first raster from your rasters list, use an index, otherwise, you will need to loop through them.
0 Kudos
Leo_KrisPalao
New Contributor II
Hi Ian,

Thanks for your reply and my apologies if my question is not clear.

What I really want is to divide each of my rasters (rasters in my folder) by a specific value, then multiply it by 100.

Raster01 / 11.2 * 100
Raster02 / 14.9 * 100
Raster03 / 9.4 * 100
Raster04 / 10.4 * 100
Raster05 / 12.4 * 100


This is why I created a list of my rasters so I can loop to all of my rasters.

rasters = [os.path.join(raster_ws, r) for r in arcpy.ListRasters()]


Also, I created a dictionary to assign a specific value for each raster. For instance Raster01 should be linked to a value 11.2. The value 11.2 will be used later as a denominator for Raster01.

rastVal = {"RE_suitable_dek001":11.2,"RE_suitable_dek002":14.9, "RE_suitable_dek003":9.4, "RE_suitable_dek004":9.4, "RE_suitable_dek005":9.4}


Thanks,
-Leo
0 Kudos
Luke_Pinner
MVP Regular Contributor
You're trying to use a list in your expression instead of a Raster object.

Change this: outRaster = rasters / rastVal[rast] * 100
To this: outRaster = Raster(rast) / rastVal[rast] * 100

http://resources.arcgis.com/en/help/main/10.2/index.html#//018z00000051000000
0 Kudos
Leo_KrisPalao
New Contributor II
Hi Luke,

Good Day!

I tried the changes that you suggested but get the following error:

Traceback (most recent call last):
  File "C:\Python27\ArcGIS10.2\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 326, in RunScript
    exec codeObject in __main__.__dict__
  File "E:\Python_scripts\ArcGIS\AWD_pct_v2.py", line 25, in <module>
    outRaster = Raster(rast) / rastVal[rast] * 100 # the equation that I want to execute...i.e., (raster1/11.2)*100
RuntimeError: ERROR 000732: Input Raster: Dataset RE_suitable_dek004 does not exist or is not supported


This is the portion of the script that I used:

for rast in rastVal: # Iterate to all raster in the directory
   outRaster = os.path.join(raster_ow, os.path.basename(rast)) # output path and filename of my raster
   if rast in rastVal: # iterate my raster if in the dictionary
      outRaster = Raster(rast) / rastVal[rast] * 100 # the equation that I want to execute...i.e., (raster1/11.2)*100
      outRaster.save(outRaster + "pct") # output raster with pct (percentage) suffix
   else:
      print "ERROR: No matching entry in raster value look up dictionary!"


I tried to change the portion of the script to arcpy.Raster(rast) but also throws the same error.

for rast in rastVal: # Iterate to all raster in the directory
   outRaster = os.path.join(raster_ow, os.path.basename(rast)) # output path and filename of my raster
   if rast in rastVal: # iterate my raster if in the dictionary
      outRaster = arcpy.Raster(rast) / rastVal[rast] * 100 # the equation that I want to execute...i.e., (raster1/11.2)*100
      outRaster.save(outRaster + "pct") # output raster with pct (percentage) suffix
   else:
      print "ERROR: No matching entry in raster value look up dictionary!"


Error:

Traceback (most recent call last):
  File "C:\Python27\ArcGIS10.2\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 326, in RunScript
    exec codeObject in __main__.__dict__
  File "E:\Python_scripts\ArcGIS\AWD_pct_v2.py", line 25, in <module>
    outRaster = arcpy.Raster(rast) / rastVal[rast] * 100 # the equation that I want to execute...i.e., (raster1/11.2)*100
RuntimeError: ERROR 000732: Input Raster: Dataset RE_suitable_dek004 does not exist or is not supported


I have problem with my list of rasters, but I am at lost how to deal with the error. I am not sure if the problem has something to do with my loop statement.

Thanks,
-Leo
0 Kudos
Luke_Pinner
MVP Regular Contributor
You either need to set the workspace to the location of the rasters (arcpy.env.workspace = path to rasters) or pass the full pathname when creating the Raster object i.e Raster(os.path.join(path to raster, rasterfilename))
0 Kudos
Luke_Pinner
MVP Regular Contributor
Change your for loop from
for rast in rastVal:

To:
for rast in rasters:

Then this should work:
outRaster = Raster(rast) / rastVal[rast] * 100
0 Kudos
Leo_KrisPalao
New Contributor II
Hi Luke, I followed your suggestion and I was able to run the script. Aside from changing in rastVal to rasters in my loop statement, I also change the name of my rasters to the fullpath:

RE_suitable_dek001:9.4 to r'Fullpath\RE_suitable_dek001:9.4

I also read this method in your post but I think you have already removed it in the thread.

Thanks very much,
-Leo
0 Kudos
Luke_Pinner
MVP Regular Contributor
I also change the name of my rasters to the fullpath:

RE_suitable_dek001:9.4 to r'Fullpath\RE_suitable_dek001:9.4

I also read this method in your post but I think you have already removed it in the thread.

I removed that post as I reread your original post and saw you were already using the full path in your script:

rasters = [os.path.join(raster_ws, r) for r in arcpy.ListRasters()]


But I forgot that you didn't use the full path in your rastVal lookup dictionary.

Please click the big check mark next to one of the above answers to indicate they answered your question.
0 Kudos