3

I am trying to replace field names of a table stored in a file geodatabase using a dictionary as a lookup table. My field names got cut off from the Tabulate Area tool (Tabulate Area Truncates Field Names in ArcGIS Pro?). The following process works, however since I have about 2,000 fields, the process is taking over an hour (and counting) to run, which defeats the purpose of making an automated tool in my case.

Is there a way to run this process faster?

I'm essentially looking to take two fields from the attribute table of my raster, turn them into a dictionary (key: value is CLASS_TRUN: Class_Name) and then replace the Tabulate Area tool output table's field names (each a unique value from CLASS_TRUN) with it's corresponding dictionary value (Class_Name).

I'm using python 3.4 for ArcGIS Pro.

classDict = {} 

with arcpy.da.UpdateCursor(in_table = supervised_tiff, field_names = ['Class_Name', 'CLASS_TRUN']) as cursor:
    for row in cursor:
        classDict[row[1]] = row[0] 

TabulateArea(in_zone_data = bad_label_shapefile, zone_field = 'crop', in_class_data = supervised_tiff, class_field = 'Class_Name', out_table = bad_sig_table)

output_table_fields = [field.name for field in arcpy.ListFields(bad_sig_table)] 

for i in output_table_fields:
    if i in classDict.keys():
        arcpy.AlterField_management(in_table = bad_sig_table, field = i, new_field_name = classDict[i], field_type = '', field_length = 64)
  • 1
    Use MakeFeatureLayer, passing a FieldInfo instance to the field_info parameter; then save that to a new output feature class. This runs much faster (though I'm sure there are scenarios in which it wouldn't), but dealing with the obnoxious FieldInfo object typically isn't worth it. – Tom Jan 8 at 19:01
  • changing 2000 field names takes you less than an hour manually? – atxgis Jan 8 at 22:31
  • @atxgis I'm trying to replace a workflow from ERDAS IMAGINE. Their version of tabulate area does not cut off field names and would take less than an hour. – Iracambi Jan 8 at 22:33
0

You can try using the 'in_memory' workspace in arcpy. This workspace does not write any data to the physical memory and only uses virtual memory space, increasing speed. I have used it in the past to speed up some geoprocessing code.

http://pro.arcgis.com/en/pro-app/help/analysis/geoprocessing/modelbuilder/the-in-memory-workspace.htm

For this to work you will have to assign your feature classes/tables to this workspace and reference it like so:

#transfer data to in_memory
arcpy.TableToTable_conversion(supervised_tiff, 'in_memory/supervised_tiff')
arcpy.TableToTable_conversion(bad_sig_table, 'in_memory/bad_sig_table')

with arcpy.da.UpdateCursor(in_table = 'in_memory/supervised_tiff', field_names = ['Class_Name', 'CLASS_TRUN']) as cursor:
for row in cursor:
    classDict[row[1]] = row[0] 
output_table_fields = [field.name for field in arcpy.ListFields('in_memory/bad_sig_table')] 

for i in output_table_fields:
    if i in classDict.keys():
        arcpy.AlterField_management(in_table = 'in_memory/bad_sig_table', field = i, new_field_name = classDict[i], field_type = '', field_length = 64)

then transfer the output to your physical workspace

arcpy.TableToTable_conversion('in_memory/bad_sig_table', 'output_tbl')

If you use in_memory let us know how well it worked

0

Here's a solution that uses FieldInfo to create an in-memory layer/view with renamed fields and then export that to a new table. Note that this works both for feature classes and for tables. See the comments for explanation:

def rename_fields(table, field_name_dict, output_table):
    """
    Rename fields in a table.

    Parameters:

    table - The path/name of the table in which fields will be renamed

    field_name_dict - A dictionary mapping input field names to the desired
        output field names

    output_table - The path/name of the output table
    """
    # Get a list of all non-required fields in the input table
    fields = [field.name for field in arcpy.ListFields(table) if not field.required]

    # Compile the FieldInfo object, based on the input field name dictionary
    f_info = arcpy.FieldInfo()
    for field in fields:
        f_info.addField(field, field_name_dict.get(field, field), 'VISIBLE', 'NONE')

    temp = 'Temp_View'

    # Since tables and feature classes require different ArcPy functions...
    #   Make a layer/view, using the FieldInfo
    #   Export the records to a new table/feature class
    if arcpy.Describe(table).datasetType == 'FeatureClass':
        arcpy.MakeFeatureLayer_management(table, temp, field_info=f_info)
        arcpy.CopyFeatures_management(temp, output_table)
    else:
        arcpy.MakeTableView_management(table, temp, field_info=f_info)
        arcpy.CopyRows_management(temp, output_table)

    return

Here's a generic example of calling the function:

my_table = r'C:\The\Path\To\My\TableOrFeatureClass'
fields_dict = {'Field1':'NewFieldName',
                'Field2':'AnotherNewFieldName'}
new_table = r'C:\The\Path\To\New\TableOrFeatureClass'
rename_fields(my_table, fields_dict, new_table)

And, here's how your code, above, would be altered to call this function:

classDict = {}

with arcpy.da.UpdateCursor(supervised_tiff, ['Class_Name', 'CLASS_TRUN']) as cursor:
    for row in cursor:
        classDict[row[1]] = row[0]

TabulateArea(in_zone_data=bad_label_shapefile, zone_field='crop', in_class_data=supervised_tiff, class_field='Class_Name', out_table=bad_sig_table)

new_table = r'C:\The\Path\To\New\TableOrFeatureClass'
rename_fields(bad_sig_table, classDict, new_table)

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.