Select to view content in your preferred language

Calculate Field Python Statement

4066
9
Jump to solution
08-21-2012 09:48 AM
by Anonymous User
Not applicable
Original User: AndrewRoberts

I have three fields in my attribute table (As seen in 1.jpg, Area1, Area2, and Area3.) I have created a new field and I wish to populate that field with the maximum value between the three fields for each feature. I've done this before with just two fields and it worked great (As seen in 2.jpg.) I tried something like this:

Expression:
Area4(!Area1!, !Area2!, !Area3!)

Code Block:
def Area4(Area1, Area2, Area3):
   if Area1 < Area2:
      return int(Area2)
   elif Area2 < Area 3:
      return int(Area3)
   else:
      return int(Area1)


but it doesn't seem to give me the desired result. I think the null values are what is giving me trouble. Any Ideas?
0 Kudos
1 Solution

Accepted Solutions
by Anonymous User
Not applicable
Original User: mdenil

try the max() function
Feed it a non-empty itterable (a string, tuple, or list)....

return max(Area1, Area2, Area3)

casting the returned value to an integer, as you do, will also truncate your floating point number towards zero. That may not be what you want.

View solution in original post

0 Kudos
9 Replies
by Anonymous User
Not applicable
Original User: mdenil

try the max() function
Feed it a non-empty itterable (a string, tuple, or list)....

return max(Area1, Area2, Area3)

casting the returned value to an integer, as you do, will also truncate your floating point number towards zero. That may not be what you want.
0 Kudos
AndrewRoberts2
Deactivated User
The statement
   return max(Area1, Area2, Area3)
Only works if there is a value for all three areas. If areas 1 and 2 have values but three is null, or any combination of this, then it doesn't work.

If I could convert the <Null>s to zeros then I believe this the 'return max() function' might work.
0 Kudos
by Anonymous User
Not applicable
Original User: ttruong

Have you try to use list instead?

MaxVal = []
rows = arcpy.SearchCursor("Your Featureclass")
for row in rows:
 MaxVal.append(row.Area1)
 MaxVal.append(row.Area2)
 MaxVal.append(row.Area3)
 arcpy.CalculateField_management("Your Featureclass", "Area4", max(MaxVal), "VB", "")
0 Kudos
curtvprice
MVP Alum
If I could convert the <Null>s to zeros then I believe this the 'return max() function' might work.


The try/except handles the issue where all are null - you'll just get null back.

Calculate Field tool:

Expression:  maxfld(!Area1!, !Area2!, !Area3!)

def maxfld(fld1,fld2,fld3):
  try:
    lst = list()
    for k in (fld1,fld2,fld3):
      if k: lst.append(k)
    return max(lst)
  except:
    pass
0 Kudos
by Anonymous User
Not applicable
Original User: ttruong

That's very odd behavior of Field Calculator.  Perhaps you should use script with updateCursor to calculate values for "Area4" if you don't want to calculate all <null> values to 0.
I did a quick test using script and I've got the right values.

import arcpy

rows = arcpy.SearchCursor("D:\Test\test.gdb\DataElements\FrequencyArea")
mylist = []
for row in rows:
    vals = (row.Area1, row.Area2, row.Area3)
    for val in vals:
        if val not in (""," ",None):
            mylist.append(val)
    print max(mylist)
    mylist = []


it returns:

IDLE 2.6.5      ==== No Subprocess ====
>>> 
6.325
2.1
>>> 


[ATTACH=CONFIG]17270[/ATTACH]
0 Kudos
AndrewRoberts2
Deactivated User
Thanks for the help, however in the end I used the original return max(Area1, Area2, Area3) solution but I manually converted my nulls to zeros so that it would work correctly.
0 Kudos
by Anonymous User
Not applicable
Original User: brucejr312

As I discovered by helping with another field calculator forum post, you can avoid having to convert null values by
passing the field to the function as integers, strings

def maxNum(num1,num2,num3):
    maxNum = max([num for num in [num1,num2,num3] if num != ''])
    return maxNum


maxNum( int(!Area1!), int(!Area2!), int(!Area3!))
0 Kudos
ThaiTruong
Deactivated User
As I discovered by helping with another field calculator forum post, you can avoid having to convert null values by
passing the field to the function as integers, strings


This is what exactly I found out at lunch today!  However, it's best to convert them to strings instead.  So you don't lose the decimal points.
0 Kudos
by Anonymous User
Not applicable
Original User: brucejr312

Actually, it would be best to pass them as int or float.  See below

>>> max(['103','1020'])
'103'
>>> 


the python max() method can't be relied upon to accurately sort string representations of numbers
0 Kudos