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).

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. – Skippy687 Sep 8 '20 at 5:18
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]
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. – Skippy687 Sep 9 '20 at 1:16
  • Nice! I've changed arcpy.DeleteField_management(fc, field) to arcpy.DeleteField_management(fc, field.name), try again – BERA Sep 9 '20 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)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.