1

I'm trying to create a Python script to automate simplifying some feature classes (shapefiles). The data table for my shapefiles look like this (all of the fields except the first four are SHORT):

FID Shape* GEOID10 EMS_ORI A_CO01 A_CO05 A_CO06 A_CO11
___________________________________________________________________________________
0 Polygon 421110218001027 E56001 99 23 99 17
1 Polygon 421110218001231 E56001 99 24 30 15
2 Polygon 421110218001028 E56001 99 24 99 16
3 Polygon 421110218001035 E56001 99 24 99 99

and so on. I am trying to find an easy way to delete an entire field if it only contains the value "99" for every row. In this example, I would want to delete the A_CO01 field because all features in this shape file have a value of 99 there. I do not want to delete A_CO06 or A_CO11, because at least one feature has a value other than 99 in each of those fields. My shapefiles have thousands of features, so I tried to script this with Python in an instant Python window in ArcCatalog. I'm only a novice at Python, so I know I'm missing something easy, but here's what I tried:

import arcpy
fc = 'E:/EMS500_Polygons.shp'
fields = arcpy.ListFields(fc)
for field in fields:
 if (field.name == "FID" or field.name == "Shape" or field.name == "GEOID10" or field.name == "EMS_ORI"):
 continue
 else:
 if (field.type = "Integer" and min(field) == 99):
 arcpy.DeleteField_management(fc, field)

This gives me a syntax error on line 10: if (field.type = "Integer" and min(field) == 99):. What I'm trying to do is delete any field where the MIN value of the entire field is 99 (this value is a "placeholder"; valid values for this field range from 1 to 93).

Vince
20.5k16 gold badges49 silver badges65 bronze badges
asked Sep 8, 2020 at 5:10
1
  • Okay, I found my stupid mistake, I have a single equal sign in if (field.type = "Integer".... I fixed it to if (field.type == "Integer" and min(field) == 99):, but now it doesn't delete any of the fields, so I'm still missing something. Commented Sep 8, 2020 at 5:18

2 Answers 2

1

min(field) will not work and should give you some error like

TypeError: 'Field' object is not iterable

Try:

import arcpy
fc = r"C:\folder\shapefile.shp"
fields = arcpy.ListFields(fc)
#Find minimum value per numeric field and store in a dictionary: "fieldname:minval"
numeric_fields = [field.name for field in fields if any(ftype in field.type.lower() for ftype in ['double', 'int'])]
values = [row for row in arcpy.da.SearchCursor(fc,numeric_fields)] #List all values for the numeric fields
mindict = {}
mindict.update({fld:val for (fld,val) in zip(numeric_fields, min(values, key=lambda x: min(y for y in x if y is not None)))})
for field in fields:
 if (field.name == "OBJECTID" or field.name == "Shape" or field.name == "GEOID10" or field.name == "EMS_ORI"):
 continue
 else:
 if 'int' in field.type.lower() and mindict[field.name] == 99:
 print(field.name)
 arcpy.DeleteField_management(fc, field.name)

To avoid listing shape and object id fields you can try using .required method:

if somefieldname not in [f.name for f in arcpy.ListFields(fc) if f.required]
answered Sep 8, 2020 at 6:33
2
  • Thank you very much. This gets me closer, but I'm still having difficulty with it. In your code, everything works up to the last line. When execution gets to there, it throws a fatal Runtime error: Runtime error Traceback (most recent call last): File "<string>", line 18, in <module> File "d:\program files (x86)\arcgis\desktop10.8\arcpy\arcpy\management.py", line 3822, in DeleteField raise e RuntimeError: Object: Error in executing tool. If I comment out that last line, it correctly lists all of the fields that I want to delete in the console window. Commented Sep 9, 2020 at 1:16
  • Nice! I've changed arcpy.DeleteField_management(fc, field) to arcpy.DeleteField_management(fc, field.name), try again Commented Sep 9, 2020 at 5:47
0

Okay, I figured it out using your example. I changed the last line to arcpy.DeleteField_management(fc, field.name) and that worked.

Here is the complete working code:

import arcpy
fc = r"E:/Shapefile.shp"
fields = arcpy.ListFields(fc)
fieldList = []
#Find minimum value per numeric field and store in a dictionary: "fieldname:minval"
numeric_fields = [field.name for field in fields if any(ftype in field.type.lower() for ftype in ['double', 'int'])]
values = [row for row in arcpy.da.SearchCursor(fc,numeric_fields)] #List all values for the numeric fields
mindict = {}
mindict.update({fld:val for (fld,val) in zip(numeric_fields, min(values, key=lambda x: min(y for y in x if y is not None)))})
for field in fields:
 if (field.name == "OBJECTID" or field.name == "Shape" or field.name == "GEOID10" or field.name == "EMS_ORI"):
 continue
 else:
 if 'int' in field.type.lower() and mindict[field.name] == 99:
 print(field.name)
 arcpy.DeleteField_management(fc, field.name)
Vince
20.5k16 gold badges49 silver badges65 bronze badges
answered Sep 9, 2020 at 1:25

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.