Here is my code:
import arcpy
import math
arcpy.env.workspace = "C:\RG\Kings County\Test.gdb"
fcs = arcpy.ListFeatureClasses("NVF_*")
try:
for fc in fcs:
rows = arcpy.UpdateCursor(fc)
for row in rows:
if row.Field_ID == 1:
rows.deleteRow(row)
del rows, row
# This code adds up several fields like Ratio_NDVI, Ratio_Acres etc.
arcpy.AddField_management (fc, "Ratio_NDVI", "float")
arcpy.AddField_management (fc, "Ratio_Area", "float")
arcpy.AddField_management (fc, "Final", "integer")-
# This code calculates area in square meter using existing datum coordinates of the vector file
arcpy.AddField_management(fc, "NewArea", "DOUBLE")
geometryField = arcpy.Describe(fc).shapeFieldName
cursor = arcpy.UpdateCursor(fc)
for row in cursor:
AreaValue = row.getValue(geometryField).area
row.setValue("NewArea", AreaValue)
cursor.updateRow(row)
del row, cursor
# This code converts square meter into acres
rows = arcpy.UpdateCursor(fc)
for row in rows:
row.NewArea = (row.NewArea*0.00024711)
rows.updateRow(row)
del rows, row
# This code calculates ratio of NDVI of child_fields to the average NDVI of parent field
rows = arcpy.UpdateCursor(fc)
for row in rows:
if row.NDVI090606 == 0:
row.Ratio_NDVI = (row.M090606/row.M090606)
else:
row.Ratio_NDVI = (row.M090606/row.NDVI090606)
rows.updateRow(row)
del rows, row
# This code calculates the ratio of acres of child fields to their corresponding parent field
rows = arcpy.UpdateCursor(fc)
for row in rows:
row.Ratio_Area = (row.NewArea/row.Acres)
rows.updateRow(row)
del rows, row
print ("Completed calculating ratio of acres")
# This code finds that field that has either Ratio_NDVI higher than 1.5 to its parent #field or less than 0.5 to its parent field and Ratio_Acres higher than 0.05. Then #comments this field as "Change"
rows = arcpy.UpdateCursor(fc)
for row in rows:
if (row.Ratio_Area > 0.05 and row.Ratio_NDVI > 1.5):
row.Final = 1
rows.updateRow(row)
if (row.Ratio_Area > 0.05 and row.Ratio_NDVI < 0.5):
row.Final = 1
rows.updateRow(row)
del rows, row
except Exception as e:
print e
In this code, how can I generalize the field name variable (row.NDVI090906). In above, NDVI090906 is a field name, where this field name follows the pattern of the name of the file. For example, if the file name is 'NVF_090906' the corresponding field name is NDVI090906. How can I make this field name as a variable so that when it loops through, it automatically performs computation of field names of other feature classes.
-
Is the end of the file name always 6 numbers? Can it include numbers? Give us some details about the file name. It may be a simple matter of parsing it apart into separate variables, but we need to know what may or may not change about the name first.Get Spatial– Get Spatial2013年09月21日 04:31:38 +00:00Commented Sep 21, 2013 at 4:31
2 Answers 2
Use row.getValue('FieldName')
instead of row.FieldName
. Using getValue lets you pass in a variable name for a field name instead of hard-coding it.
nvdi_field = 'NDVI090606'
m9_field = 'M090606'
ratio_field = 'Ratio_NDVI'
rows = arcpy.UpdateCursor(fc)
for row in rows:
if row.getValue(nvdi_field) == 0:
row.setValue(ratio_field, (row.getValue(m9_field)/row.getValue(m9_field)))
else:
row.setValue(ratio_field, (row.getValue(m9_field)/row.getValue(nvdi_field)))
rows.updateRow(row)
You can also use getattr(object, attribute)
and setattr(object, attribute, value)
on any object in Python to get a similar behavior, allowing you to program in the field name to get/set.
-
But 'NDVI090606' is the field name associated to feature class 'NVF_090606'. When the 'for' loop loops for another feature class, e.g., NVF_052013, it flags error to ndvi_field. It is because, the field name for that feature class is NDVI052013. How to handle this?Kuma– Kuma2013年09月20日 22:12:09 +00:00Commented Sep 20, 2013 at 22:12
-
Something like
nvdi_field = "NVDI" + fcnamelast
Jason Scheirer– Jason Scheirer2013年09月22日 20:05:26 +00:00Commented Sep 22, 2013 at 20:05
Give this code a shot. @Jason had the right idea with using the Get
and Set
values.
I took your code and did three things.
- I pulled the feature class name, split off the prefix, and used the second part as part of the
NDVI
andM
variables. - Replaced instances of hard-coding field names with variable references. This makes it easier if you need to change a field name, and reduces repetition.
- Combined loops that were performing separate functions. Reduces complexity of code, and multiple cycling through of rows.
I added comments to the code as necessary. I parsed the feature class name based on your filter for creating the list. You use an underscore (_) to separate the prefix of the name from the portion you want to use as part of the field names. I use that as the object to split the string. The 2nd half of the split is concatenated with a new prefix to form the two new field name variables that are unique to each featureclass.
import arcpy
arcpy.env.workspace = "C:\RG\Kings County\Test.gdb"
fcs = arcpy.ListFeatureClasses("NVF_*")
try:
for fc in fcs:
fcnamelast = fc.split('_',1)[1]
rows = arcpy.UpdateCursor(fc)
for row in rows:
if row.Field_ID == 1:
rows.deleteRow(row)
del rows, row
# This code adds up several fields like Ratio_NDVI, Ratio_Acres etc.
# Create variables containing field names first, allowing ease of reuse
fieldndvi = "Ratio_NDVI"
fieldndvichild = "NDVI" + fcnamelast
fieldm9 = "M" + fcnamelast
fieldratarea = "Ratio_Area"
fieldfinal = "Final"
fieldnewarea = "NewArea"
arcpy.AddField_management (fc, fieldndvi, "float")
arcpy.AddField_management (fc, fieldratarea, "float")
arcpy.AddField_management (fc, fieldfinal, "integer")
arcpy.AddField_management(fc, fieldnewarea, "DOUBLE")
# This code calculates area in square meter using existing datum coordinates of the vector file
#Convert square meter to acres
geometryField = arcpy.Describe(fc).shapeFieldName
cursor = arcpy.UpdateCursor(fc)
for row in cursor:
AreaSqMet = row.getValue(geometryField).area
AreaAcres = AreaSqMet * 0.00024711
row.SetValue(fieldnewarea, AreaAcres)
cursor.updateRow(row)
del row, cursor
# This code calculates ratio of NDVI of child_fields to the average NDVI of parent field
# This code calculates the ratio of acres of child fields to their corresponding parent field
rows = arcpy.UpdateCursor(fc)
for row in rows:
ndvichildval = row.getValue(fieldndvichild)
m9childval = row.getValue(fieldm9)
if ndvichildval == 0:
row.SetValue(fieldndvi, (m9childval/m9childval))
else:
row.SetValue(fieldndvi, (m9childval/ndvichildval))
#Area ratio calculation
areaacresval = row.getValue("Acres")
areanewval = row.getValue(fieldnewarea)
row.SetValue(fieldratarea,areanewval/areaacresval)
print ("Completed calculating ratio of acres")
rows.updateRow(row)
del rows, row
# This code finds that field that has either Ratio_NDVI higher than 1.5 to its parent #field or less than 0.5 to its parent field and Ratio_Acres higher than 0.05. Then #comments this field as "Change"
rows = arcpy.UpdateCursor(fc)
for row in rows:
ratareaval = row.getValue(fieldratarea)
ratndvival = row.getValue(fieldndvi)
if (ratareaval > 0.05 and ratndvival > 1.5):
row.SetValue(fieldfinal, 1)
rows.updateRow(row)
if (ratareaval > 0.05 and ratndvival < 0.5):
row.SetValue(fieldfinal, 1)
rows.updateRow(row)
del rows, row
except Exception as e:
print e