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.
Solved! Go to Solution.
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")
It's not actually too hard. N/2 will be the cumulative frequency you're looking for, so a search cursor and a few conditional statements should find your median group. Then just plug that group's range and upper and lower bands into the grouped median formula. I can write it out if you like.
if you could write it, thank you!
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[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("error")
for median in median_list :
print(median)
#obviously can add a field and append these values in rather than printing them. look at arcpy.da.UpdateCursors
Would you create one feature and check if it works for you? Please tell me what to do with this code, what window to open and where to paste. Forgive me, but I don't know coding and I really want to calculate these medians.
Rafael,
Unfortunately I dont have a home license for arcmap to test this. Do you have an IDE? If not I cant talk you through making it as a tool
Nice,
Paste it into a new .py file in IDLE
I Run Module and this popped up
Sorry change all those double equal signs to one equals sign up to and including line13