1

Using ArcGIS Desktop 10.7, I have 83 rasters that I need to loop through and perform an Extract By Attributes on using Python. Each raster has a range of values that the extracted pixels should be between. What I need to be able to do is insert the upper and lower bounding values from a table into the "where_clause".

ExtractByAttributes(in_raster, where_clause)

I'm not exactly sure how to link the appropriate values to the corresponding raster. Each raster is named after a "Map_ID" and the same "Map_ID" is located in the table. The table only has 3 columns, the Map_ID, upper and lower bounding values. The current python script I have is as follows (the 2 phrases "(Map_ID lower value)" and "(Map_ID upper value)" is what needs to call the values from a table):

# Import system modules
import arcpy
from arcpy import env
from arcpy.sa import *

# Set environment settings
arcpy.env.workspace = "C:\data\Rast_conversion_Step_1"

# set output folder
outWorkspace = "C:\data\Rast_conversion_Step_2"

# create list of rasters to perform raster math on
RasterList = arcpy.ListRasters()

for item in RasterList:
      inSQLClause = "Value >= (Map_ID lower value) and Value <= (Map_ID upper value)"
      extractRast = ExtractByAttributes(item, inSQLClause)
      outputRaster = os.path.join(outWorkspace, item)
      ExtractByAttributes.save(outputRaster)

2 Answers 2

0

Instead of looping through the rasters, use arcpy.da.SearchCursor() to loop through the table. Reference the raster with the Map_ID attribute, and build the where clause with the upper and lower bound attributes.

1
  • Thank you @Bjorn for the suggestion. Took a bit to figure out how to format a two part where clause so it wouldn't throw an error, but this approach definitely worked!
    – jjkennedy
    Commented Jul 20, 2020 at 17:53
0

I followed @Bjorn's suggestion of looping through the table instead of a list of rasters, and using the table ID to then select each raster for processing with the "ExtractByAttributes" function. This was a simple yet effective change in approach. For what it's worth this what I ended up doing. The two-part where clause made things a bit more complicated as I'm still pretty new to python and didn't know how to format that statement correctly. For clarity I split it into two parts and then combined them into one variable.

# Import system modules
import os
import arcpy
from arcpy import env
from arcpy.sa import *

Percentile_ranges = "C:\Data\All_data_10-40_percentile_ranges.csv"

output = "C:\Data\Focal_stats_output.gdb"

arcpy.TableToTable_conversion(Percentile_ranges, output, 'tempTable')
    
rast_loc = "C:\Data\Rast_conversion_Step_1"

# set output folder
outWorkspace = "C:\Data\Rast_conversion_Step_2"

fTable_1 = "tempTable"

with arcpy.da.SearchCursor(fTable_1, ["Field1", "Field2", "Field3"]) as cursor:
    for row in cursor:
        inRaster = os.path.join(rast_loc, row[0] + ".tif")
        whereclause_1 = """Value >= {}""".format(row[1])
        whereclause_2 = """and Value <= {}""".format(row[2])
        whereclause_3 = str(whereclause_1 + whereclause_2)
        extractRast = ExtractByAttributes(inRaster, whereclause_3) 
        outputRaster = os.path.join(outWorkspace, row[0]+".tif")
        extractRast.save(outputRaster)
1
  • whereclause = """Value >= {} and Value <= {}""".format(row[1], row[2]) should work
    – Bjorn
    Commented Jul 20, 2020 at 22:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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