[GIS] Model Builder/Python: batch raster calculation

arcgis-desktoparcmapiteratormodelbuilderpython

I wish to carry out a raster calculation on a batch of rasters.
I want to add rasters by month, as identified by their file name.

i.e. all rasters within the month of January should add together and output a single jan.png/raster file. Then all the rasters within Feb should add together and produce a single FEB.png.

Usually I would use raster calculator, I would prefer to automate it via either python or modelbuilder.

My plan outline is as follows:

Input Files. 36 Weekly raster files
5jan15-11jan15.png
12jan15-18jan15.png
19jan15-25jan15.png
26jan15-31jan15.png
01feb15-07feb15.png....

Raster operation.
(raster1+raster2+raster3+raster4)/(raster1+raster2+raster3+raster4) = month.png

output. 12 rasters for each month.
jan.png
feb.png
march.png

is it possible to write a python expression or create a modelbuilder which will add rasters by month using their filename?

Current Attempts

I have built a model, however this only runs on the rasters I provide it, requiring me to write a new expression each time. In other words it's the same as manually running raster calculator and writing a new expression for each month, I wish to automate this via modelbuilder.
enter image description here

Best Answer

You could do this in ModelBuilder, but it would tricky and probably require nesting models to get the iteration by month to work properly. With python, it's pretty straightforward. Here's some code to get you started:

import os, collections, re
import arcpy

arcpy.CheckOutExtension("Spatial")
arcpy.env.workspace = "<path to rasters directory>"
outdir = "<path to output dir"  

months = ["jan", "feb", "mar", "apr", "may", "jun",
          "jul", "aug", "sep", "oct", "nov", "dec"]
pat = re.compile("|".join(months))
ddict = collections.defaultdict(list)

# Create groupings of the files by month.
for raster in arcpy.ListRasters():
    res = re.findall(pat, raster)
    if res != []:
        ddict[res[0]].append(raster)    

for month,items in ddict.items():
    output = os.path.join(outdir, month + ".png")
    # Create raster objects to perform map algebra
    rasterObjs = [arcpy.Raster(it) for it in items]
    summed = sum(rasterObjs)
    rasOut = summed/summed
    # Save to disk
    arcpy.CopyRaster_management(rasOut, output)        

    # Cleanup
    try:
        arcpy.Delete_management(summed)
        arcpy.Delete_management(rasOut)
        arcpy.Delete_management(rasterObjs)
    except:
        pass
Related Question