Select to view content in your preferred language

Multiplication raster by table

5369
17
Jump to solution
10-20-2013 12:32 PM
MarcinNowak
Deactivated User
Hello,

I'm looking for the easiest way to multiply raster by the table records. Here's what I mean in details:

I have:
1) raster (DEM) - further called as "input_DEM"
2) specified numeric values stored in a table in 1 column - further called as "value_from_n_row", where 'n' is the row number

I need to create a few new rasters by this way:
"input_DEM" * "value_from_1_row" = "output_raster_1"
"input_DEM" * "value_from_2_row" = "output_raster_2"
"input_DEM" * "value_from_3_row" = "output_raster_3"
etc.

If there's a way to do this automatically? Sorry if my question is trivial, but I didn't found any solution yet.

Thanks for any support! 🙂
0 Kudos
17 Replies
XanderBakker
Esri Esteemed Contributor
Hi Matt,

When you define a path in a Python script there are 3 ways to do this (maybe more, but these are the most common ones):

# use "r" before path
myFGDB = r"C:\A\B\Test\TIMESLOOKUP.gdb"

# use forward slashes
myFGDB = "C:/A/B/Test/TIMESLOOKUP.gdb"

# use double slashes
myFGDB = "C:\\A\\B\\Test\\TIMESLOOKUP.gdb"


So in your code, change this:
arcpy.env.workspace = r"C:\A\B\Test\TIMESLOOKUP.gdb"
arcpy.env.scratchWorkspace = r"C:\A\B\Test\TIMESLOOKUP.gdb"


to this:
arcpy.env.workspace = r"C:\A\B\Test\TIMESLOOKUP.gdb"
arcpy.env.scratchWorkspace = r"C:\A\B\Test\TIMESLOOKUP.gdb"



The other thing will probably be the table "LOOKUP$". Is this by any chance an Excel worksheet? If so, you will have to reference it with its complete path, since it is not in your current workspace (which is a fgdb). If you run this in the Python window of ArcMap and the table is named like that and in your TOC, it might just work.

Kind regards, Xander

BTW: good catch with the outWS
0 Kudos
MatthewJones3
Deactivated User
Hi Xander,

Thanks for another really helpful message. As you can probably tell, I'm very new to python! I have made the changes that you suggest but I'm encountering the same error message. I have also tried closing & reopening excel and ArcMap and reloading it into the TOC.

Thanks again,
Matt
0 Kudos
XanderBakker
Esri Esteemed Contributor
Hi Matt,

There is another line in your code that will create errors:

outWS = r'C:\A\B\Test\'


The folder should not end with a slash. It should be like this:

outWS = r'C:\A\B\Test'



When writing to a folder the format will be an Esri grid (raster). This format has some limitations in naming. The most important are:

  • The maximum number of characters is 13.


  • It cannot have spaces.

  • It cannot use special characters other than underscore ( "_" ).

  • The total length of the name for a Grid and its path cannot be more than 128 characters.

You can read more about this in the Help topic on "Output raster formats and names"

Could you attach a screen shot of the Excel file you're using? I would like to see what output names are assigned.

Kind regards,

Xander
0 Kudos
MatthewJones3
Deactivated User
Hi Xander,

Please find below a screenshot of the first 12 rows of data. The first two columns are string and the third is numeric. The output names in column 1 are formatted as [year][month]_[inRaster]. There is an output name for each month of 2009 for each of the 126 input rasters.

Thanks for your continued help.

Matt
0 Kudos
XanderBakker
Esri Esteemed Contributor
Hi Matt,

I have seen issues with Esri grids that have a name starting with a number. Could you add a character at the beginning of the name (like: "R200905_001")?

I also see that the fields are named "Name", "AP" and "Q" when in the code you provided you address them as "A", "B" and "C". A, B and C and used in Excel but aren't the field names in ArcMap. Open the table in ArcMap and see what they are called.

Change:
fldName1 = 'A'
fldName2 = 'B'
fldName3 = 'C'


To:
fldName1 = 'Name'
fldName2 = 'AP'
fldName3 = 'Q'



If that doesn't work run the code below and post the text that is printed to the thread (it prints out a few rows of your data and what input and output will be used).

import arcpy,os
inWS = r'C:\A\B\C\EucDistRasters' # input rasters are stored here
outWS = r'C:\A\B\Test' # output rasters will be stored here

tbl = 'LOOKUP$'
fldName1 = 'Name' # field with output raster name (no path included)
fldName2 = 'AP' # field with input raster name (no path included)
fldName3 = 'Q' # multiply value field

fields = [fldName1,fldName2,fldName3]
cnt=0
with arcpy.da.SearchCursor(tbl, fields) as cursor:
    for row in cursor:
        cnt+=1
        value_from_row = row[2]
        inName = row[1]
        outName = row[0]
        inRasLoc = os.path.join(inWS,inName)
        outRasLoc = os.path.join(outWS,outName)
        print "Name={0}\tAP={1}\tQ={2}\t".format(outName,inName,value_from_row)
        print "  - inRasLoc ={0}".format(inRasLoc)
        print "  - outRasLoc={0}".format(outRasLoc)
        if cnt > 5:
            break

del row, tbl




Kind regards,

Xander
0 Kudos
MatthewJones3
Deactivated User
Hi Xander,

This is fantastic - it works! Placing R in front of the output filenames did the job. Thanks so much for your help. Just to clarify, in the code I was running the fields were defined correctly but I just simplified them here to A,B,C for clarity.

I'm not trying to take advantage, but I now have just one more question! - If I now want the base e exponential values of "result", should it be a simple case of adding "Exp" to the 'result' code? I have tried this but it hasn't worked (predictably). I have added import arcpy.sa to the first line of script to allow access to the toolset, but I am sure that I need to define the tool to use at some point in the script ("with arcpy.sa.exp") - I'm just not sure where!!:

>>> import arcpy,os,arcpy.sa
... arcpy.env.workspace = "C:\A\B\Test\TIMESLOOKUP.gdb"
... arcpy.env.scratchWorkspace = "C:\A\B\Test\TIMESLOOKUP.gdb"

... inWS = r'C:\A\B\C\EucDistRasters' # input rasters are stored here
... outWS = r'C:\A\B\Test\' # output rasters will be stored here
... 
... tbl = 'LOOKUP$'
... fldName1 = 'A' # field with output raster name (no path included)
... fldName2 = 'B' # field with input raster name (no path included)
... fldName3 = 'C' # multiply value field
... 
... fields = [fldName1,fldName2,fldName3]
... with arcpy.da.SearchCursor(tbl, fields) as cursor:
...     for row in cursor:
...         value_from_row = row[2]
...         inName = row[1]
...         outName = row[0]
...         inRasLoc = os.path.join(inWS,inName)
...         inRas = arcpy.Raster(inRasLoc)
...         result = Exp(inRas * value_from_row)
...         outRasLoc = os.path.join(outWS,outName)
...         result.save(outName)
... 
... del row, inRas, tbl


Your help would be greatly appreciated.

Best wishes,
Matt
0 Kudos
XanderBakker
Esri Esteemed Contributor
Hi Matt,

Sorry for the delay, but I think the expression is OK, if you change the import statement from:
import arcpy,os,arcpy.sa


to:
import arcpy,os
from arcpy.sa import *


This way the Exp function should be recognized. The alternative could be changing the line to:
result = arcpy.sa.Exp(inRas * value_from_row)


Kind regards, Xander
0 Kudos
MatthewJones3
Deactivated User
Thanks Xander, I will try this as soon as I get an opportunity and post to confirm if successful, but it doesn't seem as though it will be a problem. Thanks for getting back to me so quickly.

All the best,
Matt
0 Kudos