Select to view content in your preferred language

Assign quartile value to records in a field

780
4
10-12-2023 04:37 AM
EmekaUde
New Contributor II

Hello, I am quite new to running complex codes for field calculation tasks. 

I have a field with a number of records. I want to create another field and calculate what quartile class each record falls under say 25th, 50th, 75th or 100th. 

So basically I need help to calculate and determine the quartile class of each records in a particular field.

Thank  you for your help

 

0 Kudos
4 Replies
DuncanHornby
MVP Notable Contributor

You can complete this task with some python scripting which you can run directly within ArcPro from the python console.

Here is an example table of my input layer, 12 rows with the values I want to put into quartile classes in the field Value and QClass is the field to record which class they are in, note the rows are all NULL as the code has yet to be run.:

DuncanHornby_0-1698423118363.png

 

The code you drop into the python console is this, you just need to change the layername and fields in the search and update cursors to match your data.:

 

import arcpy, numpy
layername = "testdata" # Name of layer as seen in TOC
lstValues = list()     # list to store values in

# Read values into list
with arcpy.da.SearchCursor(layername, "Value") as cursor:
    for row in cursor:
        lstValues.append(row[0])

# Use numpy to compute quartiles
q25 = numpy.percentile(lstValues, 25)
q50 = numpy.percentile(lstValues, 50)
q75 = numpy.percentile(lstValues, 75)
print("Q25 = " + str(q25))
print("Q50 = " + str(q50))
print("Q75 = " + str(q75))

# Write quartile class back to layer
with arcpy.da.UpdateCursor(layername, ["Value","QClass"]) as cursor:
    for row in cursor:
        v = row[0] # The value
        if v < q25:
            row[1] = 25
        elif v >= q25 and v < q50:
            row[1] = 50
        elif v >= q50 and v < q75:
            row[1] = 75
        else:
            row[1] = 100
        cursor.updateRow(row)

Print("Finished!")

 

 

The results are shown, sorted by QClass:

DuncanHornby_1-1698423496988.png

 

0 Kudos
EmekaUde
New Contributor II

Thank you @DuncanHornby for the solution you posted above. I did run the code (plate 2) but it came back with an error (plate 3)

How can you help please?

 

plate 1.jpgPlate 2.JPGPlate 3.JPG

0 Kudos
DuncanHornby
MVP Notable Contributor

OK, well done for showing your workings and its because you made the effort to show me I can make an educated guess! Your layername is "New_parval_SpatialJoin". The clue is in the name... I'm guessing you have done a spatial join with the new Add Spatial Join tool?  Well if you open your attribute table and move your cursor over the Tree_can field header, I'm going to guess its not Tree_can but something like "somelayer_spatial_Join.Tree_can"? Thats the fully qualified field name of the field because its a joined field. So what you see is what you need to use in your cursors.

0 Kudos
EmekaUde
New Contributor II

Hi @DuncanHornby, I figured it out. Actually, it was not because of the spatial join. The issue was that I had about three 'null' records in the Tree_can field. After populating the null cells with zeros, I was able to execute the code successfully to obtain the expected results.

0 Kudos