Select to view content in your preferred language

Calculating median in grouped data using ArcMap

6828
53
Jump to solution
01-31-2020 10:46 AM
RafaelMichael
Occasional Contributor

I got stuck when calculating the median age in grouped data (age ranges) for each feature (each feature is a single administrative unit). I have about 18,000 features.

Field names indicate age ranges: 0-14, 15-64, 65-100. In the "median" field I would like to calculate the median age for each feature. I found a website https://atozmath.com/StatsG.aspx?q=1 where you can calculate such a median for a single feature, for example the first feature from the attribute table above.

The page easily calculated the median for the first feature in the image, and the page also wrote how it calculated it, but I don't know how to write a universal script for a "median" field to calculate the median for each feature.

0 Kudos
53 Replies
DavidPike
MVP Frequent Contributor

You're very welcome.

RafaelMichael
Occasional Contributor

There is one more problem. I have over 18 thousand features in total, but IDLE printed 10 thousand, that is, the IDLE skipped features for which it is impossible to calculate the median. If I pasted IDLE values into the attribute table, they would go to the wrong place. Can you correct the code so that there are also values for objects for which the median cannot be calculated? For example, "null" or 0 would appear. I would be very grateful

0 Kudos
DavidPike
MVP Frequent Contributor
import arcpy

input_table = r'put the path to your table here'

#lcb is the lower class boundary
width_age_range_1 = 14.5
lcb_age_range_1 = 0.0

width_age_range_2 = 50.0
lcb_age_range_2 = 14.5

width_age_range_3 = 35.5
lcb_age_range_3 = 64.5

median_list = [ ]

with arcpy.da.SearchCursor(input_table, ["TOT", "TOT_0_14",  "TOT_15_64", "TOT_65"]) as cursor :


    
    for row in cursor :

        #if all numeric fields hopefully
        n_over2 = (row[0]/2.0)
        
        if row[0] == 0 :
            median_list.append(-9999)
            continue
         

        if row[1] >= n_over2 :
            #cumulative freq of groups before median group
            cumu_freq = 0.0
            if row[1] != 0.0 :
                median = lcb_age_range_1 + ( ((n_over2 - cumu_freq)/row[1]) * width_age_range_1)
                median_list.append(median)
                continue
            continue
        
        if (row[1] + row[2]) >= n_over2 :
            #cumulative freq of groups before median group
            cumu_freq = row[1] 
            if row[2] != 0.0 :
                median = lcb_age_range_2 + ( ((n_over2 - cumu_freq)/row[2]) * width_age_range_2)
                median_list.append(median)
                continue
            continue

        if (row[1] + row[2] + row[3]) >= n_over2 :
            #cumulative freq of groups before median group
            cumu_freq = row[1] + row[2]
            if row[3] != 0.0 :
                median = lcb_age_range_3 + ( ((n_over2 - cumu_freq)/row[3]) * width_age_range_3)
                median_list.append(median)
                continue
            continue

        else:
            median_list.append(-999)

#for median in median_list:
    #print(median)

counter = 0

    
with arcpy.da.UpdateCursor(input_table, ["median"]) as cursor :
    for row in cursor :
        if counter < len(median_list):
            row[0] = median_list[counter]
        
            try :
                cursor.updateRow(row)
                counter += 1
            except :
                print("error at count - "  + str(counter))

        else:
            break
        

print("complete")          

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
RafaelMichael
Occasional Contributor

0 Kudos
DavidPike
MVP Frequent Contributor

edited 

RafaelMichael
Occasional Contributor

0 Kudos
DavidPike
MVP Frequent Contributor

edited

RafaelMichael
Occasional Contributor

0 Kudos
DavidPike
MVP Frequent Contributor

edited

RafaelMichael
Occasional Contributor

0 Kudos