Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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.

share|improve this question
    
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 Sep 21 '13 at 4:31

2 Answers 2

up vote 1 down vote accepted

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.

  1. I pulled the feature class name, split off the prefix, and used the second part as part of the NDVI and M variables.
  2. 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.
  3. 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
share|improve this answer
    
It did work. Thanks –  Kuma Sep 23 '13 at 17:56

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.

share|improve this answer
    
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 Sep 20 '13 at 22:12
    
Something like nvdi_field = "NVDI" + fcnamelast –  Jason Scheirer Sep 22 '13 at 20:05

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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