0

I am new to Python and am having trouble figuring out how to reclassify over 500 rasters so that any values are equal to 1 and no data is equal to 0.

Here is my code with the error code at the bottom:

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

#Set environment settings
env.workspace = "E:/GIS_2017/Shapefiles"

#Set local variables
inputDir = "E:/GIS_2017/Shapefiles/TestRasters/projected"
outputDir= "E:/GIS_2017/Shapefiles/TestRasters/projected/re1"
outputsuffix = "re"

rasList = arcpy.ListRasters()
for raster in rasList:
    inRaster = raster
    remap = RemapValue([[11002,1],[11004,1],[11005,1],[11006,1],[11007,1],[11009,1],[11015,1],[11013,1],[11014,1],[11016,1],[11019,1],[11029,1],[11030,1],[11036,1],[11043,1],[11044,1],[11046,1],[11048,1],[11049,1],[11050,1],[12039,1],[12040,1],[12042,1],[12123,1],[80002,1],[80003,1],[80004,1]])
    outReclassify = Reclassify(inRaster, "Value", remap, "NODATA")
    outRasterName = '{}{}'.format(raster, outputsuffix)
    outReclassify.save(env.path.join(outputDir, outRasterName)
    print "outRasterName Reclassified Successfully!"

Parsing error SyntaxError: invalid syntax (line 21)

is there a better way to do this? Each raster layer only has one value which is one of the codes specified in the remap.

2
  • 1
    You need to close both parentheses on line 20, the one with outReclassify.save
    – Jacob F
    Commented Jun 23, 2017 at 0:25
  • 1
    SyntaxError is because of a missing closing parenthesis. Voting to close as off-topic.
    – user2856
    Commented Dec 4, 2017 at 0:00

3 Answers 3

1

Yes! There is a better way. If I understand correctly your rasters all have one value, and you want them all to have the same value?

The following solution uses the Con function from spatial analyst. It will only work if your rasters don't contain other values you wish to preserve in the range 8000 - 13000 (which is what I've used based on a quick scan of your remap table keys.

Basic usage is:

Con(conditional statement, value_if_true, {value_if_false}, {where clasue})

As the docs say you can ignore the where clause and use map algebra in the conditional statment. the value if true and value if false can be constants or rasters.

So you're code would look something like:

rasList = arcpy.ListRasters()
for raster in rasList:
    inRaster = Raster(raster)
    outCon = Con(((inRaster > 8000) & (inRaster2 < 13000)), 1, inRaster)
    outRasterName = '{}{}'.format(raster, outputsuffix)
    outCon.save(env.path.join(outputDir, outRasterName))
    print "{} Reclassified Successfully!".format(outRasterName)

You can think about what the Con statement does as traversing the raster cell by cell, and for the value at each location evaluate whether 8000<value<13000 is true. If it is true the output raster has a value of 1 at that location. If it is false the output raster has the same value as the input raster at that location.

Finally you can chain con statements together if you have several ranges or values to reclassify to by inserting a new Con as the value_if_false this is a little bit mind boggling if you're not used to recursion/nesting functions, but often much faster than reclassify if you're just dealing with numbers.

In your case this would be something like:

outRas = Con((inRaster>8000)&(inRaster<8006), 1, 
            Con((inRaster>11000)&(inRaster<11050), 1, 
                Con((inRaster>12000)&(inRaster<12050), 1, inRaster)
            )
         )
1
  • I didn't consider the con tool, but can see how it might make the process faster than reclassifying. I will attempt this, thank you!
    – Allie
    Commented Jun 23, 2017 at 23:23
0

In addition to @RopeyMaps, you need to handle your noData with the con tool. You must use IsNull(), otherwise NoData will still be NoData.

rasList = arcpy.ListRasters()
for raster in rasList:
    inRaster = Raster(raster)
    outCon = Con(IsNull(inRaster), 0, 1)
    outCon.save(inRaster[:-4] + "_recl.tif") 
2
  • Won't that set all the noData values to 1? and the rest to 0?. I would imagine you meant Con(IsNull(inRaster), 0, inRaster), which would set noData to 0 and leave everything else the same. I ignored noData since the workflow I suggested will just carry noData values through which I assumed wouldn't be a problem given it wasn't asked about.
    – RoperMaps
    Commented Jun 23, 2017 at 9:50
  • thanks for your remark. I've edited so that values other than NoData are set to 1, and equal to noData to 0
    – radouxju
    Commented Jun 23, 2017 at 11:15
0

Thanks for the help! I have it out, here are two separate scripts I created. One reclass was done to change all values to 1, then the rasters were aggregated in model builder (where processing extent, snap raster, and raster mask were specified) then I ran the second reclass script. It turned out nicely where rasters were set to binary: 1's and 0's.

Reclass1:

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

env.workspace = "E:/GIS_2017/Shapefiles/BD_projected"
outputDir = "E:/GIS_2017/RasterData/Reclass1.gdb"
outputsuffix = "r1"

rasList = arcpy.ListRasters()
for raster in rasList:
    inRaster = raster
    remap = RemapValue([[11002,1],[11004,1],[11005,1],[11006,1],[11007,1],[11009,1],[11015,1],[11013,1],[11014,1],[11016,1],[11019,1],[11029,1],[11030,1],[11036,1],[11043,1],[11044,1],[11046,1],[11048,1],[11049,1],[11050,1],[12039,1],[12040,1],[12042,1],[12123,1],[80002,1],[80003,1],[80004,1]])  

outReclassify = Reclassify(inRaster, "Value", remap, "NODATA")  
outRasterName = '{}{}'.format(inRaster, outputsuffix)

outReclassify.save(os.path.join(outputDir, outRasterName))

print outRasterName + " Reclassified Successfully!"

Then rasters were aggregated

Reclass2:

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

env.workspace = "E:/GIS_2017/RasterData/Aggregated.gdb"


outputDir = "E:/GIS_2017/RasterData/Reclass2.gdb"
outputsuffix = "r2"

rasList = arcpy.ListRasters()
for raster in rasList:
    inRaster = raster
    remap = RemapRange([[1, 29, 0],[29, 289, 1],["NODATA", "NODATA", 0]])
    outReclassify = Reclassify(inRaster, "Value", remap, 0)


    outRasterName = '{}{}'.format(inRaster, outputsuffix)

    outReclassify.save(os.path.join(outputDir, outRasterName))


    print outRasterName + " Reclassified Successfully!"

Not the answer you're looking for? Browse other questions tagged or ask your own question.