4

I am trying to do a calculations under arcpy.da.UpdateCursor. I want to calculate the values for the records that have FIPS=06037. I want to take the values from "kg" column and populate the new value by multiply by 3 in "kg_new" column.

I think I am not using the right syntax under

row_field_Name[0] = "!kg!"*3

and for the next FIPS in the shapefile , i.e. FIPS=06308,

I want to take the "kg"value and multiply by 5.

    # Set the workspace environment
arcpy.env.workspace = r"E:\Test_Errors_onE\myPath"
arcpy.env.overwriteOutput = True

infc = "myFile.shp"
#Add a new filed named
field1 = ["kg"]

field_Name = "kg_new"
field_Nametype = "DOUBLE"
field_Namename = arcpy.ValidateFieldName(field_Name)
#arcpy.AddField_management(infc, field_Name, field_Nametype, "", "", "")


cursor = arcpy.da.UpdateCursor(infc, field_Name, "\"FIPS\" = 06307")
for row_field_Name in cursor:
    row_field_Name[0] = "!kg!"*3
    cursor.updateRow(row_field_Name)

cursor = arcpy.da.UpdateCursor(infc, field_Name, "\"FIPS\" = 06308"")
for row_field_Name in cursor:
    row_field_Name[0] = "!kg!"*5
    cursor.updateRow(row_field_Name)
  • Is FIPS a string field? "\"FIPS\" = 06308"" with the leading 0 seems to suggest that. – Michael Stimson Mar 10 '15 at 1:50
1

It seems you've got a little confused with the field syntax, "!kg!" is the python syntax when used in field calculator ONLY.

I think this is what you're after:

import arcpy
arcpy.env.workspace = r"E:\Test_Errors_onE\myPath"
arcpy.env.overwriteOutput = True

infc = "myFile.shp"
#Add a new filed named
fields_in_cursor = ["kg","kg_new"] # kg is 0, kg_new is 1

field_Name = "kg_new"
field_Nametype = "DOUBLE"
field_Namename = arcpy.ValidateFieldName(field_Name)

# add field if it does not exist
fList = arcpy.ListFields(infc,field_Name)
if not fList:
    arcpy.AddField_management(infc, field_Name, field_Nametype, "", "", "")

with arcpy.da.UpdateCursor(infc, fields_in_cursor, "\"FIPS\" = '06307'") as cursor:
    for row_field_Name in cursor:
            row_field_Name[1] = row_field_Name[0]*3
            cursor.updateRow(row_field_Name)

with arcpy.da.UpdateCursor(infc, fields_in_cursor, "\"FIPS\" = '06308'") as cursor: 
    for row_field_Name in cursor:
            row_field_Name[1] = row_field_Name[0]*3
            cursor.updateRow(row_field_Name)

First, with arcpy.da cursors you limit the fields with a list, then index them in the order of inclusion.

Second, it's important to delete your cursors! or you will leave locks on the data and the edits may not be properly committed. This is true for arcpy. cursors and arcpy.da. cursors (only arcpy.da. cursors support with) I have put in a with statement that gets rid of the cursor when it's done.

Third, when selecting from a string field you must quote the value. In this case "\"FIPS\" = '06307'" is for string, "\"FIPS\" = 06307" is for a number (leading 0 is removed, becoming "\"FIPS\" = 6307". Quotes are optional: a query of "FIPS = '06307'" works the same as "\"FIPS\" = '06307'" when used as a definition query in a cursor. The only time that it's absolutely essential (that I have found) to use quotes is when performing field calculations (not the target field, only the source field).

  • Hi Michael Miles-Stimson, Thank you very much for your suggestions and some tips. Yes, I didn’t realize that I had to delete the cursor at the end. No wonder why when I opened the shapefile in ArcGIS, the programs said the file being locked. I tried to run your code but this line: using arcpy.da.UpdateCursor(infc, fields_in_cursor, "\"FIPS\" = '06307'") as cursor: has a syntax error. – Jook Mar 12 '15 at 16:10
  • Oops! using is the C# word, it should be with. Try it without the quotes: with arcpy.da.UpdateCursor(infc, fields_in_cursor, "FIPS = '06307'") as cursor: if FIPS isn't a string field then with arcpy.da.UpdateCursor(infc, fields_in_cursor, "FIPS = 6307") as cursor: would be more appropriate. Sorry, I've got 4 programming languages on the go at the moment and sometimes I get them mixed up. – Michael Stimson Mar 12 '15 at 21:06
  • Dear Michael Miles-Stimson, with arcpy.da.UpdateCursor(infc, fields_in_cursor, "FIPS = '06307'") works now. Thank you very much for your help. This saves me a lot of time doing things manually on ArcGIS. – Jook Mar 18 '15 at 15:10
5

I would use the following approach which incorporates logic to check for your "FIPS" code.

import arcpy

fc = r"E:\Test_Errors_onE\myPath\myFile.shp"

with arcpy.da.UpdateCursor(fc, ["FIPS", "kg", "kg_new"]) as cursor:
    for row in cursor:
        if row[0] == 06307:
            row[2] = row[1] * 3
        if row[0] == 06308:
            row[2] = row[1] * 5
        cursor.updateRow(row)
  • 1
    Good point Aaron, that would be an excellent (and more efficient) way to perform this task. – Michael Stimson Mar 10 '15 at 2:01
  • Hi Aaron, thank you very much for your suggestions. The code works. I've tested both if the values are numeric or string (re: Michael Miles-Stimson comments). For numeric, the zero at the front gets chopped off in the shapefile. For string, I need to put '' around the number, e.g. '06307'. – Jook Mar 12 '15 at 15:54
0

I like Aaron's approach but depending on the size of your dataset and how many different FIPS values you have, this could be slow. That method iterates over all entries in the FC.

I'd say combine the two suggestions with an OR where clause:

with arcpy.da.UpdateCursor(infc, fields_in_cursor, "FIPS = '06307' OR FIPS = '06308'") )
......

Then apply Aaron's method.

This cuts down on the records you're traversing.

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.