0

I have 4 fields (STREAMS, SLOPE_ASPECT, FIRES, TREES) that are assigned either a 1 or a 0 based on whether they exist or not.

The goal: Create a new field "ranking" the best locations (essentially, where all four = 1)

The assignment says "Create a RANK field and calculate the sum of the 4 fields". I am currently trying to use a SearchCursor and InsertCursor from another question about something similar but this results in no change and continues displaying "NULL". I am very new to this.

Here's what I've got:

SearchArea = r'C:...'
fc = SearchArea
#Establish local variable for Ranks field
MushroomRanks = "RANKS"
newFields = ['STREAMS', 'SLOPE_ASPECT', 'FIRES', 'TREES', 'RANKS']
#Add RANKS field
arcpy.AddField_management(SearchArea, MushroomRanks, "SHORT")
#Create a variable for our SUM
values = []
#Search cursor to calculate the sum of new fields and store them into a "values" variable
with arcpy.da.SearchCursor(fc, newFields) as Scursor:
    thisValue = 0
    for row in Scursor:
    thisValue += row[0]
    values.append(thisValue)
newFields.append(MushroomRanks)
#Inserts the stored sums
with arcpy.da.InsertCursor(fc, MushroomRanks) as cur:
      cur.insertRow(values)

1 Answer 1

5

Your code appears to attempt to copy all the "STREAMS" values (row[0]) to the "RANKS" field and ignores all the other fields (row[1:4]).

But then you use an InsertCursor instead of an UpdateCursor and attempt to append those "STREAM" values as new rows instead of updating the "RANK" field in the existing rows.

You could do this with a simple Calculate Fields expression without any scripting at all, e.g.

sum([!STREAMS!, !SLOPE_ASPECT!, !FIRES!, !TREES!])

Or if if you want to use arcpy:

arcpy.management.CalculateField(
    fc, MushroomRanks, 
    "sum([!STREAMS!, !SLOPE_ASPECT!, !FIRES!, !TREES!])", 
    "PYTHON3")

But if you must use a cursor, use an UpdateCursor not an InsertCursor and there's no need for a SearchCursor at all:

with arcpy.da.UpdateCursor(fc, newFields) as rows:
    for row in rows:
        row[-1] = sum(row[:-1])  # sum all values except the last and assign to the last (row[-1])
        # Does the same as
        # row[4] = sum(row[0:4]) # sum 1st 4 values and assign to the 5th (row[-1])
        rows.updateRow(row)     
2
  • Worked like a charm! I wasn't able to get the UpdateCursor to work, it returned: "line 94, in <module> rows.updateRow(row) StopIteration: iteration not started" However, the CalculateField is all I needed for this one, I had to play around with cursors before reaching this point so I think I was just overthinking it. Thank you for the notes and help with the syntax of the rows in the Update cursor, that will come in handy. I greatly appreciate your help and guidance! Commented Jul 2, 2023 at 6:38
  • For some reason, I lost an indentation level when I pasted the UpdateCursor code. Should be fixed now. I noticed, but neglected to refer to it, that your indentation is incorrect in the line after ` for row in Scursor:`. Don't forget python uses indentation as part of the language syntax.
    – user2856
    Commented Jul 2, 2023 at 7:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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