I am very rusty/inexperienced in Python.
I would like to create a more compact script that prints min and max values of each numeric field from a feature class. Right now I have the code below repeated for each field that contains numeric values.
How would I code this to identify if a field has numeric values and then print the min and max values to the python shell or even better to a .csv/text file?
import arcpy
data = "C:/Workfolder/Input.gdb/FeatureClass"
listname = []
cursor = arcpy.da.SearchCursor(data, "field1")
for row in cursor:
listname.append(int(row[0]))
print 'Field1_min, {0}'.format(min(listname))
print 'Field2_max, {0}'.format(max(listname))
3 Answers 3
I think one of the efficient options would be using where
and sql_clause
arguments of arcpy.da
, for example:
field_to_find_min_max = "MyFieldName"
min_value = arcpy.da.SearchCursor(data, field_to_find_min_max, "{} IS NOT NULL".format(field_to_find_min_max), sql_clause = (None, "ORDER BY {} ASC".format(field_to_find_min_max))).next()[0]
max_value = arcpy.da.SearchCursor(data, field_to_find_min_max, "{} IS NOT NULL".format(field_to_find_min_max), sql_clause = (None, "ORDER BY {} DESC".format(field_to_find_min_max))).next()[0]
This also makes sure the only non-NULL values are processed (where clause).
Another way to calculate the minimum is to use the SummaryStatistics function.
To iterate through the fields, use the ListFields function:
# Create a list of fields using the ListFields function
fields = arcpy.ListFields(feature_class)
# Iterate through the list of fields
for field in fields:
if(field.type == 'Integer' or field.type == "Double"):
#calculate the minimum using SummaryStatistics
Using the list is clever, or at least it seems until you get to a very large feature class. Instead of the list:
import arcpy
data = "C:/Workfolder/Input.gdb/FeatureClass"
cursor = arcpy.da.SearchCursor(data, "field1")
FirstRecord = True
for row in cursor:
if FirstRecord:
FirstRecord = False
MinValue = int(row[0])
MaxValue = int(row[0])
else:
MinValue = min(int(row[0]),MinValue)
MaxValue = max(int(row[0]),MaxValue)
print 'Field1_min, {0}'.format(MinValue)
print 'Field2_max, {0}'.format(MaxValue)
Or using Summary Statistics:
import arcpy
data = "C:/Workfolder/Input.gdb/FeatureClass"
arcpy.Statistics_analysis(data,r"c:\WorkFolder\Input.gdb\StatTable",[["Field1","min"],["Field1","max"]])
cursor = arcpy.da.SearchCursor(r"c:\WorkFolder\Input.gdb\StatTable",["Field1_min","Field1_max"])
row = cursor.next()
print "Field1 Min = %s, Field1 Max = %s" % (str(row[0]), str(row[1]))
del row
del cur
arcpy.Delete_management(r"c:\WorkFolder\Input.gdb\StatTable")
Be careful that field1 is, or can be converted to, an integer. If it's a date or string field you're gonna have problems!
-
Thank you for the heads up. This will reclassify the fields in my feature class as integers then? listname.append(int(row[0]))user29499– user294992014年06月10日 17:02:32 +00:00Commented Jun 10, 2014 at 17:02
-
It will, if they can be converted to int: short int, long int, double and float can be converted to int. Some text can be converted to int but first you need to check if it can - stackoverflow.com/questions/354038/…Michael Stimson– Michael Stimson2014年06月10日 21:17:46 +00:00Commented Jun 10, 2014 at 21:17
-
1@user29499 listname.append(int(row[0])) will reclassify the value of row[0] to integer, but it won't reclassify the field in the feature class as integerStephen Lead– Stephen Lead2014年06月10日 23:40:16 +00:00Commented Jun 10, 2014 at 23:40
-
Good point @StephenLead, it will change the value obtained from the field, if it can, but not the field itself. So if the field is a double the value obtained is converted to an int but the field itself remains unchanged - a double. Generally speaking field types can't be changed; there are ways but it's risky and could destroy the data.Michael Stimson– Michael Stimson2014年06月10日 23:45:02 +00:00Commented Jun 10, 2014 at 23:45