I am trying to iterate through features and perform a ZonalHistogram using each row. I am iterating using a SearchCursor. ZonalHistogram requires that I specify the zone field. When specifying the zone field of 'statsZone' I get the error below. I've ensured that this field does in fact exist.

enter image description here

import arcpy
import datetime
import os
import os.path
from arcpy import env
from arcpy.sa import *

newlayer = arcpy.mapping.Layer('D:/myshapefile.shp')
rasterLayer = "D:/myRaster.tif"
outputDirectory = "D:/myOutputLocation/"

with arcpy.da.SearchCursor(newlayer,["SHAPE@",'statsZone']) as cursor:
    for row in cursor:
        arcpy.gp.ZonalHistogram_sa(row[0], 'statsZone', rasterLayer, outputDirectory+row[1]+".dbf", "")
  • 1
    Run print([field.name for field in arcpy.ListFields(newlayer)]) and confirm that statsZone shows up in that list.
    – Tom
    Jun 5 '18 at 14:58
  • @Tom - I know its in the shapefile.. I can delete the last line in the cursor and it will print the value for statsZone on each feature (e.g. row[1])
    – jotamon
    Jun 5 '18 at 15:03
  • Oh, I see. You're passing a geometry object as the first argument to ZonalHistogram, when you should be passing a layer. See the documentation: desktop.arcgis.com/en/arcmap/10.4/tools/spatial-analyst-toolbox/…
    – Tom
    Jun 5 '18 at 15:10
  • @Tom - ahha - Sounds like I need to make a temporary selection or something and then pass that to the ZonalHistogram function?
    – jotamon
    Jun 5 '18 at 15:14
  • But you will only have one zone per run anyway, because you're iterating rows. I'm not sure what you need, but it sounds to me like you should skip the cursor and just pass newlayer as the first argument to a single run of ZonalHistogram.
    – Tom
    Jun 5 '18 at 15:18

Zonal Histogram is expecting a feature layer with fields like statsZone, not a geometry (row[0]) which has no fields.

Try using the SearchCursor to return each ObjectID instead and use it to create a feature layer for each row. Then use this as input:

arcpy.env.overwriteOutput = True
with arcpy.da.SearchCursor(newlayer,'OID@') as cursor:
    for row in cursor:
        sql = """{0} = {1}""".format(arcpy.AddFieldDelimiters(newlayer, arcpy.Describe(newlayer).OIDFieldName), row[0])
        arcpy.gp.ZonalHistogram_sa('templyr', 'statsZone', ...

Exporting each feature will probably run correctly, but you'll end up with 27,000 histograms. Is that what you want?

If there are no overlaps in your input shapefile, I would recommend converting the shapefile to raster, based on the statsZone field. Be sure to set the cell size, snapping, etc. as needed (for easier processing, they should be identical to that of your rasterLayer). Then run ZonalHistogram with the new raster as the first argument.

  • Yeah.. I tried this but the results were inconsistent and buggy.. I am able to process the 27k histograms in R so the one-at-a-time method seems to work pretty well.
    – jotamon
    Jun 5 '18 at 17:44
  • @jotamon, Out of curiosity, what was inconsistent/buggy with that?
    – Tom
    Jun 5 '18 at 18:33
  • Often times certain features were not summarized or differing dimensions of final DBF were produced.
    – jotamon
    Jun 5 '18 at 22:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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