Convert field types in GDB with Python

4709
4
Jump to solution
06-11-2015 07:18 PM
PV
by
New Contributor III

I want to create a python script (ArcGIS 10.1) where I loop through a GDB with several feature classes  and select all the fields which are of text type and convert them to float type. I always want to skip the first 10 and last 2 fields of each featureclass as they actually are supposed to be of text type. I am not quite sure how to do so.. I guess FeatureClassToFeatureClass_conversion does the trick but I am a bit lost.

This is as far as I got:

(I asked the same question on Stackexchange as I need an answer asap: http://gis.stackexchange.com/questions/150723/convert-field-types-in-gdb-with-python)

# Import system modules
import arcpy
from arcpy import env
env.overwriteOutput = True

# Set environment settings
env.workspace = "D:\Test\2011_LongNames.gdb"

inFeatures = arcpy.ListFeatureClasses("*")
outLocation  = "D:\Test\FLOAT.gdb"
outName = ??? same as inFeature

field_mapping = ???? part where it converts text fields to float fields

listFCs = [f.name for f in arcpy.ListFields(env.workspace)]
listFCs = listFCs[10:len(listFCs)-2)]

for fc in listFCs:
    arcpy.FeatureClassToFeatureClass_conversion(inFeatures, outLocation, outName, field_mapping )
0 Kudos
1 Solution

Accepted Solutions
curtvprice
MVP Esteemed Contributor

The field mapping object manipulation you ask about is a pretty heavy lift of Python programming for beginners. If you are still up to it, here's the basic idea. "fms" is the FieldMappings object you can use with FeatureClassToFeatureClass.

Even with the complexity of the FieldMappings object methods and properties, this does still seem easier to me than dinking with NumPy arrays and such to simply change the data type of your fields... assuming the structure of your 100 tables are identical.

fc = listFCs[0]
fms = arcpy.FieldMappings()
fms.addTable(fc)
nfields = len(arcpy.ListFields(fc))
# skip fields 0,1 (OID, Shape), next 10, and the last two
for fi in range(2 + 10, nfields - 2):
   fmap = fms.getFieldMap(fi)
   ofield = fmap.outputField
   ofield.type = "Double" # change from String to Double
   fmap.outputField = oField
   fms.replaceFieldMap(fi, fmap)

for fc in listFCs:  
   outName = inFeatures
   arcpy.FeatureClassToFeatureClass_conversion(inFeatures, outLocation, outName, fms) 

FieldMappings—Help | ArcGIS for Desktop

View solution in original post

4 Replies
DanPatterson_Retired
MVP Emeritus

If you have many files, or want to do this many times, scripting it with data access cursors...field addition and removal... or arrays are at least 3 options.  If this is a one off venture...do it manually...if you anticipate doing this again...get the data type right in the first place.  In short...here are your options

I would also recommend PolyGeo's suggestion on GISStackExchange...

  • add the new fields,
  • copy the values over...
  • remove the old fields.

Or using data access conversions to numpy arrays by bringin the file into NumPy,:

  • exploding to points using FeatureClassToNumpyArray
  • do the dtype conversion on the array changing from int32 to float64,
  • then export back to a new file using  NumPyArrToFeatureClass and reassemble the shapes (some of this is covered on my Blog and there may be some issues with shapes with holes or multipart shapes which are tricker to handle).

Or, again using Numpy:

  • simply export the table using TableToNumPyArray
  • do the conversion type (since you are rescaling) then
  • export that table to ArcMap using NumPyArrayToTable which you can then
  • join to the original feature class using the object/feature ID field.
  • save to a new file so that all the fields are permanent in one file, then delete the fields you don't want.

Any process may seem a bit onerous...however, this can all be accomplished within a script if you like, but the manual process is quick particularly if you only have a few fields to delete or a few files to do...In your case, you have 10 fields so adding fields manually with the proper data type, copying the old field values over, deleting the original field etc may take about the same time.

PV
by
New Contributor III

Thanks for the input!
In Fact I have over 200 fields for more than 100 feature classes so I cannot do it manually..

I failed with PolyGeo's idea as I am not good with Python, even if the way sounds quite logical to me but I give an update if I can make it work with the NumPy!

0 Kudos
curtvprice
MVP Esteemed Contributor

The field mapping object manipulation you ask about is a pretty heavy lift of Python programming for beginners. If you are still up to it, here's the basic idea. "fms" is the FieldMappings object you can use with FeatureClassToFeatureClass.

Even with the complexity of the FieldMappings object methods and properties, this does still seem easier to me than dinking with NumPy arrays and such to simply change the data type of your fields... assuming the structure of your 100 tables are identical.

fc = listFCs[0]
fms = arcpy.FieldMappings()
fms.addTable(fc)
nfields = len(arcpy.ListFields(fc))
# skip fields 0,1 (OID, Shape), next 10, and the last two
for fi in range(2 + 10, nfields - 2):
   fmap = fms.getFieldMap(fi)
   ofield = fmap.outputField
   ofield.type = "Double" # change from String to Double
   fmap.outputField = oField
   fms.replaceFieldMap(fi, fmap)

for fc in listFCs:  
   outName = inFeatures
   arcpy.FeatureClassToFeatureClass_conversion(inFeatures, outLocation, outName, fms) 

FieldMappings—Help | ArcGIS for Desktop

PV
by
New Contributor III

Thank you a lot Curtis! The code worked when I tested it on a GDB with 2 feature classes with the same field names. However, I had to completed the process in FME as I have different field names in all FC and couldn't find it out how to do it with a script on time (Python is not really my strength..) ! Will definitively use it in the future though!

0 Kudos