4

I am trying to find the largest and the second largest value in a row from my shapefield table. The largest is easy to find with the max() expression. The second largest is quite easy to find in Python via:

a = [VALUE_1,VALUE_2,VALUE_3,VALUE_4,VALUE_5]
a.sort()
print a[-2]

If I use the same code in the field calculator I get the message that VALUE_1 is not defined. But I stated the input in the expression.

enter image description here

2
  • Can you screenshot your field calculator input? Hard to debug without seeing it.
    – Dùn Caan
    May 9, 2017 at 14:30
  • I have updated my answer to include multiple columns or multiple rows
    – Midavalo
    May 9, 2017 at 14:55

2 Answers 2

7

You can use a Search Cursor to find the values in your field, and then return the two highest values through the Field Calculator

In the Pre-logic script code:

vals = []
with arcpy.da.SearchCursor("testPoint", ['intfield']) as cursor:
    for row in cursor:
        vals.append(row[0])
vals.sort()

def maxvals(fieldval):
    global vals
    if fieldval in vals:
        if fieldval in [vals[-1], vals[-2]] :
            return fieldval

And in the expression:

maxvals( !intfield!)

Where !intfield! is the name of the field you want to search in, and "testPoint" is the name of your layer

In Field Calculator window:
enter image description here

In Calculate Field geoprocessing tool:
enter image description here

And the result:
enter image description here


Upon re-reading your question, it sounds like you want to look across multiple fields to find the max and next values.

Max Value Pre-logic code:

def maxnum(fields):
    fields.sort()
    return fields[-1]

Second-max Value Pre-logic code:

def maxnum(fields):
    fields.sort()
    return fields[-2]

Expression:

maxnum([!intfield!, !intfield2!, !intfield3!, !intfield4!])

Pass your fields as a list here in your expression.

Field Calculator window:
enter image description here

Calculate Field:
enter image description here

Result:
enter image description here

0
2

You need to change your codeblock to something like:

def a(VALUE_1,VALUE_2,VALUE_3):
    vals = [VALUE_1,VALUE_2,VALUE_3]
    vals.sort()
    return vals[0]

It would be better practice to rewrite the expression as something like:

getMax(!VALUE_1!,!VALUE_2!,!VALUE_3!)

And change your codeblock to:

def getMax(VALUE_1,VALUE_2,VALUE_3):
        vals = [VALUE_1,VALUE_2,VALUE_3]
        vals.sort()
        return vals[0]

Bear in mind this only returns the max value, if you want the second largest value, use return vals[1], or if you want the sum of the largest and second largest, use return vals[0] + vals[1]

1
  • 1
    Just realised Midavolo's answer includes a slightly more concise version of this answer - use that!
    – Dùn Caan
    May 9, 2017 at 15:05

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.