Currently working on a Median calculation tool. This tool is similar to the one I posted on a previous post involving selecting a city and zooming into it. In this case, we have to type in a country name, where the tool will then select all the cities in that country, sort the POP_RANK of the cities in that country, and calculate the median POP_RANK for that country. I was able to complete the select and zoom aspect but I am not entirely sure how to create a list/search cursor which will allow us to input a calculation. Is there a specific way I should approach this? Any and all help is appreciated!! Thank you
import arcpy
from arcpy import mapping
#sets the workspace
mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
fc = ("N:/data2016/Lab13/cities.shp")
cities = arcpy.mapping.ListLayers(mxd, "Cities")[0]
cities.showLabels = True
def countryList():
country = arcpy.GetParameterAsText(0)
country_Layer = arcpy.MakeFeatureLayer_management(fc, "country_lyr")
arcpy.SelectLayerByAttribute_management(cities, "NEW_SELECTION", "CNTRY_NAME = '{}' ".format(country))
arcpy.mapping.ListDataFrames(mxd)[0].zoomToSelectedFeatures()
arcpy.RefreshActiveView()
arcpy.Delete_management("country_lyr")
SearchCursor—Help | ArcGIS for Desktop example 2 shows how to ge the unique values.. if you leave out the set(...) bit, you have all the values, which then you can then use a python sort, get the len(gth) and if len is divisible by 2 (mod), just take the average of the middle 2 (from len/2 and len/2 +1) otherwise if len is odd, just take the middle one.
alternately that field can be read and converted to a numpy array for which there are median methods for data with and without nodata values.
forgot the code link http://www.arcgis.com/home/item.html?id=6c384f06c9f14d09920f4ff14460f4e2
and your chance to join a cause to free statistical tools Free Frequency ... join the cause
If you install ArcGIS Pro, you will be using python 3.4 which comes with the Statistics module, which has 4 variants of the median which covers most useable situations 9.7. statistics — Mathematical statistics functions — Python 3.4.4 documentation
Does anyone in the 'global reach' section have any further ideas? or should I mark this 'assumed answered'
There was a median calculation tool posted here somewhere by Caleb Mackey.
But no joy with search. So here it is again.
''' Written By Caleb Mackey 4/17/2013 Calculates Median Statistics ''' import arcpy, os, sys, traceback # env settings arcpy.env.overwriteOutput = True arcpy.env.qualifiedFieldNames = False def GetMedian(in_list): sorted_list = sorted(in_list) median = int(round(len(sorted_list) / 2)) if len(sorted_list)%2==0: med_val = float(sorted_list[median-1] + sorted_list[median]) / 2 else: med_val = sorted_list[median] return med_val def GetMedianValues(source_fc, new_table, case_field, value_field): ''' Generates a table with Median Values, summarized by case_field. If the goal is to get the median for the entire table, use a case field that has the same value for all records. source_fc - input feature class to compute median statistics for new_table - output table case_field - similar to dissolve field, computes stats based on unique values in this field value_field - field that contains the actual values for statistics; must be numeric ''' # Get unique value list for query print 'starting cursor' with arcpy.da.SearchCursor(source_fc, [case_field]) as rows: un_vals = list(set(r[0] for r in rows)) lyr = arcpy.MakeFeatureLayer_management(source_fc,'source_layer') values = {} # Get Median UseValue for each station name for st in un_vals: query = '"{0}" = \'{1}\''.format(case_field, st) arcpy.SelectLayerByAttribute_management(lyr, 'NEW_SELECTION', query) use_vals = [] with arcpy.da.SearchCursor(lyr, [value_field]) as rows: for row in rows: if row[0] != None: use_vals.append(row[0]) if len(use_vals) > 0: median = GetMedian(use_vals) values[st] = [median, len(use_vals)] # Create new Summary Statistics table with median # if arcpy.Exists(new_table): arcpy.Delete_management(new_table) arcpy.CreateTable_management(os.path.split(new_table)[0],os.path.basename(new_table)) # Get field names and types for field in arcpy.ListFields(source_fc): if field.name in [case_field, value_field]: ftype = field.type name = field.name length = field.length pres = field.precision scale = field.scale if name == value_field: if new_table.endswith('.dbf'): name = 'MED_' + value_field[:6] else: name = 'MED_' + value_field value_field2 = name arcpy.AddField_management(new_table,name,ftype,pres,scale,length) # Add frequency field arcpy.AddField_management(new_table,'FREQUENCY','LONG') # Insert rows with arcpy.da.InsertCursor(new_table, [case_field, value_field2, 'FREQUENCY']) as rows: for k,v in sorted(values.iteritems()): rows.insertRow((k, v[0], v[1])) # report results print 'Created %s' %os.path.basename(new_table) arcpy.AddMessage('Created %s' %os.path.basename(new_table)) # .dbf's are automatically given a 'Field1' field...Clean this up try: if new_table.endswith('.dbf'): arcpy.DeleteField_management(new_table, 'Field1') except: pass print 'Done' if __name__ == '__main__': ## # testing ## source_fc = r'C:\Testing\Test.gdb\CSR_by_TWP' #### new_table = r'C:\Testing\Test.gdb\Median_CSR' #gdb test ## new_table = r'C:\Testing\Median_CSR.dbf' #dbf test ## case_field = 'NAME' ## value_field = 'AVE_CSR' # Script tool params source_fc = arcpy.GetParameterAsText(0) new_table = arcpy.GetParameterAsText(1) case_field = arcpy.GetParameterAsText(2) value_field = arcpy.GetParameterAsText(3) GetMedianValues(source_fc, new_table, case_field, value_field)
so if using recent versions of python, it would still be easier to use the builtins
>>> import statistics
>>> a = [1,2,3]
>>> statistics.median(a)
2
>>> b = [1,2,3,4]
>>> statistics.median(b)
2.5
>>>
>>> dir(statistics)
['Decimal', 'Fraction', 'StatisticsError', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_check_type', '_counts', '_decimal_to_ratio', '_exact_ratio', '_ss', '_sum', 'collections', 'math', 'mean', 'median', 'median_grouped', 'median_high', 'median_low', 'mode', 'pstdev', 'pvariance', 'stdev', 'variance']
>>>
Of course Dan,
But I am running 10.3.1 (soon moving to 10.4).
Haven't got anywhere near Pro yet. Need to buy a deep blue before I do.
I have been using python 3.4 since arcmap 10.2... it is a matter of setup
I think we have it wrapped up with this one, in case it is a network question