[GIS] ArcGIS python “add field” and “calculate field” workflow

arcgis-10.1arcpyfield-calculatorfields-attributes

I am new in Python and I am creating a Script. I've crafted a functional code, but I'd like to know if there is an easier way to do it, just for curiosity (And learning new ways!).

The purpose of the Script is to create 5 fields in a polygon shape (previously drawn) and to calculate their values.

My code is this:

import arcpy

env.workspace = "C:/Users/...."

#First, create the fieldlist with a loop for. With this I'll create the table
fieldlist = ["Area","Longitude","Latitude","MaxDepth","MinDepth"]
for field in fieldlist:
    arcpy.AddField_management(My_shapefile,field,"dobule")

#And now calculate fields
arcpy.CalculateField_management(My_shapefile,"Area","!shape.area@squarekilometers!","PYTHON_9.3")
arcpy.CalculateField_management(My_shapefile,"Longitude","!shape.extent.XMax!","PYTHON_9.3")
arcpy.CalculateField_management(My_shapefile,"Latitude","!shape.extent.YMax!","PYTHON_9.3")
arcpy.CalculateField_management(My_shapefile,"MaxDepth","!shape.extent.ZMin!","PYTHON_9.3")
arcpy.CalculateField_management(My_shapefile,"MinDepth","!shape.extent.ZMax!","PYTHON_9.3")

Best Answer

Updating multiple fields will be much faster with UpdateCursor. That way your code will iterate through the features once, instead of five times (one for each CalculateField_management call).

cursorFields = ["SHAPE@"] + fieldlist
with arcpy.da.UpdateCursor("My_shapefile", cursorFields) as cursor:
    for row in cursor:
        geom = row[0]
        row[1] = geom.area # update Area field
        row[2] = geom.extent.XMax # update Longitude field
        row[3] = geom.extent.YMax # update Latitude field
        row[4] = geom.extent.Zmin # update MaxDepth field
        row[5] = geom.extent.ZMax # update MinDepth field
        cursor.updateRow(row) # commit the changes

Also, the values you're calculating don't quite line up with their field names since you're grabbing from the extent property. If it's point data it won't make a difference, but it may make your code intention a little clearer if you access the point geometry properties directly (e.g. geom.centroid.x for Longitude and so on).

Related Question