Select to view content in your preferred language

Changing field names in python script

4006
6
05-13-2014 09:22 AM
CharliePeterson
Emerging Contributor
Hello All,

The short and sweet version is this:

I want to:

  1. Read the list of fields in a shapefile

  2. check for a field starting with "Pri*"

  3. If it is not named "Priority", I want to rename them to "Priority"

I use the Priority field as the Case field in the next tool (summary stats) and
some of the shapefiles have the field as "Priority_1" or something similar.


prifield = arcpy.ListFields(preparedfeatures, 'Pri*')
 try:
  if prifield != "Priority":
   arcpy.AddWarning('The priority field was named ' + str(prifield) + " and will be renamed.")
   arcpy.AddField_management(preparedfeatures, "Priority", "SHORT", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")
   arcpy.CalculateField_management(preparedfeatures, "Priority", prifield , "PYTHON_9.3", "")
 except:
  arcpy.AddWarning(arcpy.GetMessages())
  continue



What prints in the console is this:
"The priority field was named [<Field object at 0x19b708f0[0x18f993b0]>] and will be renamed."

So clearly it is not reading the field names properly.


I have read about arcpy.Alterfield_management, but it reportedly does not work with shapefiles.

I have also tried iterating over the fields using the field index and looking for the field name I want, but no luck.
Thanks for your help.
Tags (2)
0 Kudos
6 Replies
IanMurray
Honored Contributor
Hi Charlie

A few things.  First off, prifield = arcpy.ListFields(preparedfeatures, 'Pri*'), makes prifield a list filled with all the fields that meet your parameters.  To get individual fields from this list you need to use a for loop or indexes.  Secondly, it is not incorrect what it was returning, it was returning the space on your hard drive where the data is stored.  To get the actual name value of the field you need to call .baseName on it or .aliasName

So you would need something like
prifield = arcpy.ListFields(preparedfeatures, 'Pri*')
for field in prifield:
  if field.baseName != "Priority":
    arcpy.AddWarning('The priority field was named ' + str(field.baseName) + " and will be renamed.")
    arcpy.AddField_management(preparedfeatures, "Priority", "SHORT", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")
    arcpy.CalculateField_management(preparedfeatures, "Priority", field , "PYTHON_9.3", "")



more on getting info about fields can be found here

http://resources.arcgis.com/en/help/main/10.2/index.html#//018z0000004n000000

Hope this helps you.
0 Kudos
CharliePeterson
Emerging Contributor
Great info!

Thanks!

Only issue now is transferring the values from the old field to the new one

How do I get the values from the original field to transfer over to the new field?

Again, I would ideally like to just rename the field, any ideas on that?
I tried adding
field.baseName = "Priority" after the If. Still no luck

 try:
  arcpy.Statistics_analysis(preparedfeatures, sumstattblnum, "AREA_GEO SUM", "Priority")
 except:
   for field in fields:
   if "Pri" in field.baseName:
    if field.baseName != "Priority":
     wrongname = field
     arcpy.AddWarning('The priority field was named ' + str(field.baseName) + " and will be renamed.")
     arcpy.AddField_management(preparedfeatures, "Priority", "SHORT", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")
     arcpy.CalculateField_management(preparedfeatures, "Priority", field, "PYTHON_9.3", "")
   else:
    arcpy.AddMessage('%s had the proper fields. There must be some other error.' % preparedfeatures_str)
    arcpy.AddWarning(arcpy.GetMessages())


The new field is all 0's rather than the contents of the original 'Priority_1' field.

Thoughts?
0 Kudos
IanMurray
Honored Contributor
I didn't really review the calculate field parameters before writing my response earlier

arcpy.CalculateField_management(preparedfeatures, "Priority", "!" + field.baseName + "!", "PYTHON_9.3", "")
  
should be used, as the 3rd parameter needs to be an SQL expression for the field name, not the field name itself. 

I'm not sure about actually changing the field name with python, you'd at minimum would have to open an editting session and even then you probably could only edit the Alias Name, not the Base Name.  I could be completely wrong about that, someone please correct me if I am. 

Hope this helps
0 Kudos
CharliePeterson
Emerging Contributor
Awesome. The following worked just as intended.

oldfield = str(field.baseName)
'(!' + oldfield + '!)'

Thanks!
0 Kudos
curtvprice
MVP Esteemed Contributor
I want to:
* Read the list of fields in a shapefile
* check for a field starting with "Pri*"
* If it is not named "Priority", I want to rename them to "Priority"


A far more efficient way to complete this operation is to use the Merge_management tool with a field map to make a new copy of your shapefile with the field names and order just the way you want them.

The FieldMappings and FieldMap objects are a little tricky but not too difficult once you figure them out.
0 Kudos
CharliePeterson
Emerging Contributor
A far more efficient way to complete this operation is to use the Merge_management tool with a field map to make a new copy of your shapefile with the field names and order just the way you want them.

The FieldMappings and FieldMap objects are a little tricky but not too difficult once you figure them out.


Is this truly the more efficient way? (To note: I don't care about the order at all. I simply need a field called "Priority" so I can use it as a case field in Summary Stats.)

Additionally, part of my code that I didn't include in the original post was an iterator that goes through >1000 shapefiles.

It seems wasteful to create all new shapefiles just to rename 1 field.
EDIT: I just re-read your post and it clicked that you meant create one large shapefile (merge).
Although I still see the size of the file (merging >1000 shapefiles with 10-100+ features each) as a potential problem since I don't know all the possibilities for the name of the "pri*" field.
And, finally, field mapping seems like it would be tricky if I don't know the exactly field I want to map.

Thoughts?
0 Kudos