0

My Table

I am trying to update the table above. What I want to do is if the values in the PMP fields are less than the Max fields update the check fields with PASS, if not FAIL. I started doing this trying to create a list for the PMP fields and a list for the MAX fields and comparing them and updating a check list that I would use to populate the CHECK fields but had issues.

Could this be done using just an Update cursor or numpy somehow?

Here is what I had so far on my list attempt.

    pmpValues = []
    i = 0
    for pmpVal in pmpFields:
        with arcpy.da.SearchCursor(checkTable,pmpFields[i]) as cursor:
            for row in cursor:
                pmpValues.append([row])
        i += 1

    maxValues = []
    i = 0
    for maxVal in maxFields:
        with arcpy.da.SearchCursor(checkTable,maxFields[i]) as cursor:
            for row in cursor:
                maxValues.append([row])
        i += 1        

    checkValues = []
    for p in pmpValues:
        for m in maxValues:
            if p < m:
                check = "FAIL"
            else:
                check = "PASS"
            checkValues.append(check)

2 Answers 2

0

Here's how you could use an update cursor without having to worry about field order (untested):

# use a wildcard to return all fields for each row
with arcpy.da.UpdateCursor(fc, '*') as cursor:
    # grab the field names
    fields = cursor.fields
    # loop over rows
    for row in cursor:
        # create dict of field name -> field value
        rec = dict(zip(fields, row))
        # loop over dict keys and values
        for k, v in rec.iteritems():
            # act on PMP fields only
            if not k.startswith('PMP_'):
                continue
            # split the the numeric suffix from the PMP field name
            _, n = k.split('_')
            # lookup the max value for that given suffix
            mx = rec['MAX_{}'.format(n)]
            # set the CHECK value for that given suffix in our dict
            rec['CHECK_{}'.format(n)] = 'FAIL' if v < mx else 'PASS'
        # update values from the dict, ensuring that the order matches the row
        cursor.updateRow([rec[k] for k in fields])
2
  • Don't use cursor.fields in a loop. It's a relatively expensive operation and you better do it once right after with ... as statement (and store it into something like cur_fields). Doing it so saved me around 70% of process time once. Jan 24, 2019 at 12:58
  • @SergeNorin, good tip. I just did a comparison reading 20 fields from 10,000 rows using a SearchCursor. Accessing the attribute outside of the loop was about 10x faster. Updated my answer.
    – mikewatt
    Jan 24, 2019 at 17:16
0

You can use a modified version of the UpdateCursor code sample from http://desktop.arcgis.com/en/arcmap/10.3/analyze/arcpy-data-access/updatecursor-class.htm

With the update cursor, you pass your set of desired fields and can evaluate each row, then pass new values for each field/record.

import arcpy

fc = 'pathtofeatureclass'
fields = ['PMP_06', 'MAX_06', 'CHECK_06','PMP_12', 'MAX_12', 'CHECK_12','PMP_24', 'MAX_24', 'CHECK_24','PMP_48', 'MAX_48', 'CHECK_48']

# Create update cursor for feature class 
with arcpy.da.UpdateCursor(fc, fields) as cursor:
    # For each row, evaluate each PMP field value (index position 0,3,6,9)
    # vs MAX value (index position 1,4,7,10) 
    # and update CHECK (index position of 2,5,8,11)
    for row in cursor:
        if row[0] < row[1]:
            row[2] = 'PASS'
        else:
            row[2] = 'FAIL'
        if row[3] < row[4]:
            row[5] = 'PASS'
        else:
            row[5] = 'FAIL'
        if row[6] < row[7]:
            row[8] = 'PASS'
        else:
            row[8] = 'FAIL'  
        if row[9] < row[10]:
            row[11] = 'PASS'
        else:
            row[11] = 'FAIL'
        # Update the cursor with the updated list
        cursor.updateRow(row)
1
  • Thank you so much for your response! That would be perfect if the fields were static. The only problem is the number of fields can change based on duration. This table is the output of another tool. The fields are for each duration run. The example has 6,12,24,ect.. However, the user could choose 1,2,3,4,5,6.... so adding a static row number doesn't really work.
    – Jake
    Jan 18, 2019 at 19:15

Your Answer

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

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