3

have encountered a problem, in Field Calculator.

The situation : I have a polygon feature with a table, comprised of a single Field ("Field1"). There are 675 records in this field. The minimum value is 0.24, and the maximum value is 2546.

What I want to do: Add a new field ("Field2"), in which I want to generate the normalized values in "Field1". By normalization, I am referring to re-scaling all the values, from 0 to 1.

What functions / expression can I use in Field Calculator, to obtain these normalized values?

3 Answers 3

6

Using Python would open up some more elegant solutions, but you can do this entirely in ModelBuilder with the use of a couple of temporary tables. The model would look something like this (note that you can right-click on any process step and rename it):

enter image description here

  1. The Add Field operation adds a new column called [Normalized_Value] to your existing polygon table.
  2. A pair of Sort operations create two new tables, one with your [Field1] sorted in ascending order, and the other sorted in descending order.
  3. A pair of Get Field Value operations get the first row (the minimum and maximum values) of [Field1] and assign them to %Min_Value% and %Max_Value%, respectively. The values are available for use automatically as soon as these steps have run.
  4. The min and max values are then used in the Calculate Field operation to calculate [Normalized_Value]: (([Field1] - %Min_Value%) / (%Max_Value% - %Min_Value%))
  5. (Optional) You may wish to add steps to delete the temporary tables.
0
3

You could use the Python parser in the Field Calculator and construct this function.

This part goes in the pre-logic. Make sure to replace the feature classes with the one from your system. The feature class table called "Temp_Table" is a temporary table and must reside in a geodatabase. It will be deleted as the script completes.

def normNum(num):
  arcpy.Statistics_analysis(r'C:\Geodatabase.gdb\Original_Features',r'C:\Geodatabase.gdb\Temp_Table', [["Field1","MIN"],["Field1","MAX"]])
  with arcpy.da.SearchCursor(r'C:\Geodatabase.gdb\Temp_Table', ("MAX_Field1" , "MIN_Field1")) as cursor:
    for row in cursor:
      maxNum = row[0]
      minNum = row[1]
  del cursor
  del row
  arcpy.Delete_management(r'C:\Geodatabase.gdb\Temp_Table')
  return ((num - minNum) / ( maxNum - minNum))

This part goes in the "Field2 =" box:

normNum(!Field1!)

Here is a version that would run as stand alone function so you wouldn't need the field calculator:

def NormalizedNumbersToField(table, field, scratchGDB):
    arcpy.AddField_management(table, "NORMALIZED", "DOUBLE")
    scratchTable = os.path.join(scratchGDB, "Temp_Feat")
    arcpy.Statistics_analysis(table,scratchTable, [[str(field),"MIN"],[str(field),"MAX"]])
    with arcpy.da.SearchCursor(scratchTable, ("MAX_" + str(field) , "MIN_" + str(field))) as cursor:
        for row in cursor:
            maxNum = row[0]
            minNum = row[1]
    del cursor, row
    arcpy.Delete_management(scratchTable)
    with arcpy.da.UpdateCursor(table, ( field , "NORMALIZED" )) as cursor:
        for row in cursor:
            number = row[0]
            row[1] = (( number - minNum ) / ( maxNum - minNum ))
            cursor.updateRow(row)
    del cursor, row
0
1

You could do something like this...

[Field2] = (( [Field1] - 0.24 ) / ( 2546 - 0.24 ))

Basically you have to find the difference between the [Field1] value and the minimum value and then divide it by the entire range of data.

normalized = (value - minimum) / (maximum - minimum)
3
  • Yes, I agree about the formula, but instead of using "0.24" in the formula, I would like to use "MIN[Field1]" (or how the correct version the syntax is spelled). I want to use "generic" syntax, because this formula will be used in a Model Builder. (Sorry I forgot to mention that I will be using it in Model Builder)
    – Andrei
    Commented Mar 27, 2015 at 16:29
  • And The same goes for 2546. Instead of manually typing the value, I would like to use the generic expression for "Maximum" in that field ("Field1"). I haven't previously worked with complex expressions, especially between different fields. So what would the overall expression be like, considering it will be used in Model Builder (and manual value typing won't be an option) ?
    – Andrei
    Commented Mar 27, 2015 at 16:33
  • Okay, that makes it a bit tougher but not to bad. Python is probably the way to go.
    – GeoJohn
    Commented Mar 27, 2015 at 18:32

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.