I am trying to calculate the percentage of each the area of each polygon in the selected area.

I tried using ( math.fsum(!shape.area!) / !PolygonArea! )*100 and other codes but I cannot make it work.

Suggestions on how to solve this?


The field calculator cannot do a summary without employing a cursor, and the calculation must use the code block to work. The cursor should only be run once, so you need to make the cursor code populate a global vaeiable or dictionary with the first record and then skip the cursor code for all other records.

In the example below I assume you have a case field for grouping called CASE_FIELD so you can calculate percentages for all of your polygons based on their group using only one calculation. That way you don't have to do separate selections and calculations for each polygon case group. This specific code is untested, but it was based on the proven code and principles outlined in my blog on Creating Labels with Related Table Data:

Parser: Python

Use Code Block: Checked

Pre-Logic Script Code:

areaDict = {}
def percentage(case, shape_area)
  global areaDict
  if len(areaDict) == 0:  
    # Provide the path to the feature class you are calculating
    areaFC = r"C:\Users\USERNAME\Documents\ArcGIS\YourGeodatabase.gdb\YourFC"  
    # create a field list with the case field first (example: CASE_FIELD),   
    # followed by the area field (SHAPE@AREA)  
    areaFieldsList = ["CASE_FIELD", "SHAPE@AREA"]  
    # process a da search cursor to transfer the data to the dictionary  
    with arcpy.da.SearchCursor(areaFC, areaFieldsList) as areaRows:  
      for areaRow in areaRows:  
        # store the key value in a variable so the relate value   
        # is only read from the row once, improving speed  
        areaKey = areaRow[0]  
        # if the area key of the current row isn't found   
        # create the key and make it's value the area of the record  
        if not areaKey in areaDict:  
          areaDict[areaKey] = areaRow[1]
          # if the area key is already in the dictionary   
          # accumulate the area by summing for the given case field  
          areaDict[areaKey] += areaRow[1]
    # delete the cursor, and row to make sure all locks release  
    del areaRows, areaRow
  if case in areaDict:
    return shape_area / areaDict(case) * 100.0
    return none

Expression: percentage(!CASE_FIELD!, !shape.area!)

Edit: Changed @SHAPE field in cursor field list to SHAPE@AREA field per the help for the SearchCursor

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.