Select to view content in your preferred language

arcpy.DeleteField_management

7666
7
11-30-2012 12:58 PM
KeisukeNozaki
Frequent Contributor
I know it is possible to specify which fields to delete using arcpy.DeleteField_management.
However, when there are many fields, I would rather like to specify which fields to keep (i.e. delete all fields but those fields).
I appreciate your help.
Tags (2)
0 Kudos
7 Replies
by Anonymous User
Not applicable
KEI!!!

Nice to see you on the forums :).

Try this:

import arcpy
# Local Variables
address = r'G:\Testing\textTest\addtest.shp'
keep = ['FID','FULL_ADD', 'ESN', 'CITY', 'ZIP']  # be SURE to include FID/OBJECTID field here!

try:
    discard = []
    for field in [f.name for f in arcpy.ListFields(address)if f.type <> 'Geometry']:
        if field not in keep:
            discard.append(field)
    arcpy.DeleteField_management(address, discard)
   
except:
    arcpy.GetMessages(2)

0 Kudos
curtvprice
MVP Esteemed Contributor
There's an old ArcInfo Workstation command that did this (PULLITEMS) with INFO tables. I miss it.

A list comprehension is definitely the right approach here.

This has a bit more checking, because:
- You can't delete the OID field
- Shape_Length and Shape_Area cause DeleteField to throw an exception.

keepList = ["FIELD1","FIELD2"]
fieldNames = [f.name for f in arcpy.Describe(inTable).Fields if not \
    (f.type in ["OID","Geometry"] or \
    f.name in ["Shape_Length","Shape_Area"] or \
    f.name.upper() in  keepList )]
if fieldNames:
    arcpy.DeleteField_management(inTable,fieldNames)
0 Kudos
by Anonymous User
Not applicable

- You can't delete the OID field


I was wondering about that... I like your method with the field type check.  I just discovered the geometry field check this morning.  I found that this also works, but I like your method better 🙂

import arcpy
# Local Variables
address = r'G:\Testing\textTest\addtestCopy.shp'
keep = ['FULL_ADD', 'ESN', 'CITY', 'ZIP']

try:
    discard = []
    for field in [f.name for f in arcpy.ListFields(address)if f.type <> 'Geometry']:
        if field not in keep:
            if field == 'FID' or field == 'OBJECTID':
                pass
            else:
                discard.append(field)
    print discard  
    arcpy.DeleteField_management(address, discard)
    print 'done'
   
except:
    arcpy.GetMessages(2)


After taking another look, I think this is the easiest:

keep = ['FULL_ADD', 'ESN', 'CITY', 'ZIP']
discard = []
    for field in [f.name for f in arcpy.ListFields(address) if f.type <> 'OID' and f.type <> 'Geometry']:
        if field not in keep:
            discard.append(field)  
    arcpy.DeleteField_management(address, discard)
    print 'done'
0 Kudos
OlgaKraynova
Emerging Contributor
This thread is quite old, but I still hope for getting some advice. I found posted codes very useful and applied their variation several times very successfully. I'm very grateful to you guys for sharing it. However, recently I faced with very strange behavior of the code.
So, what i'm trying to achieve is to join shapefile with feature class and then delete all unnecessary fields except needed. Both input files has same field names so that after join the output file has fields like this: CID, TYPE, STATUS, X, Y, CID_1, TYPE_1, STATUS_1 etc. This is fine. But deleting unnecessary fields in the output doesn't work and I can't figure out why.

from arcpy import env
try:
    env.qualifiedFieldNames = False
    inFeature = scratch+"\\SK.shp"
    inLayer  = "SK_lyr"
    joinFeature  = current+"\\SK_Point"
    joinLayer = "SK_Point_lyr"
    inLayerField  = "CID"
    joinLayerField = "CID"
    outFeature = current+"\\SK_Poly"

    arcpy.MakeFeatureLayer_management(inFeature, inLayer)
    arcpy.MakeFeatureLayer_management(joinFeature, joinLayer)
    arcpy.AddJoin_management(inLayer, inLayerField, joinLayer, joinLayerField, "KEEP_ALL")
    arcpy.CopyFeatures_management(inLayer, outFeature)
    

except Exception, e:
    import traceback, sys
    tb = sys.exc_info()[2]
    print "Line %i" % tb.tb_lineno
    print e.message

infc = current+"\\SK_Poly"
keep = ["CID", "TYPE", "STATUS", "X", "Y"]

try:
    discard = []
    for field in [f.name for f in arcpy.ListFields(infc) if f.type <> 'OID' and f.type <> 'Geometry']:
        if field not in keep:
            discard.append(field)
    arcpy.DeleteField_management(infc, discard)
    
except:
    arcpy.GetMessages(2)
0 Kudos
by Anonymous User
Not applicable
I'm not sure what is going wrong.  Maybe try using your original outFeature variable rather than creating another variable.  Also, have you tried printing out the names of the fields from the output to make sure they are correct in your keep list?

keep = ["CID", "TYPE", "STATUS", "X", "Y"]
discard = [f.name for f in arcpy.ListFields(outFeature)
           if f.type not in ('OID', 'Geometry')
           and f.name not in keep]:
arcpy.DeleteField_management(outFeature, discard)
0 Kudos
OlgaKraynova
Emerging Contributor
Same result...
According to the layer properties all field names are correct. Also i noticed that field ALIASES in the output file have same names (without _1 for fields of the joined file at the end) while field NAMES of the joined file have _1 at the end. It looks like the code reads aliases instead of actual names. Is it possible?
0 Kudos
OlgaKraynova
Emerging Contributor
I really don't know why it doesn't work in this script while works in others... maybe the reason is in files themselves, maybe they are broken somehow or in a mix of feature classes and shapefiles. No idea. Anyway, I found a workaround for this problem based on the script sample from ArcGIS Recourse center (http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//00170000004n000000):

from arcpy import env
try: 
    inFC = current+"\\SK_Poly"
    updatedFC = scratch+"\\Test.shp"
 
    desc = arcpy.Describe(inFC)
 
    arcpy.CopyFeatures_management(inFC, updatedFC)
     
    fieldObjList = arcpy.ListFields(updatedFC)
 
    fieldNameList = []
 
    keep = ["CID", "TYPE", "STATUS", "X", "Y"]

    for field in fieldObjList:
       if not field.required and field.name not in keep:
            fieldNameList.append(field.name)
 
    arcpy.DeleteField_management(updatedFC, fieldNameList)
          
except Exception, e:
    # If an error occurred, print line number and error message
    import traceback, sys
    tb = sys.exc_info()[2]
    print "Line %i" % tb.tb_lineno
    print e.message
0 Kudos