Mapping input fields to output fields
A common geoprocessing task is to merge many datasets into a new or existing dataset to create a single dataset covering a larger area or a table containing a greater number of records. Often, the attributes, or fields, are the same for all the inputs that are used in a merge or append operation; sometimes, however, they do not match, and the relationships between fields of different names and types have to be mapped. For an example of field mappings, see the Merge tool in the Data Management toolbox; it facilitates this mapping of relationships so data is placed in the desired output fields with the correct values.
The FieldMap object provides a field definition and a list of input fields from a set of tables or feature classes that provide its values.
The properties of the FieldMap object include the start and end position of an input text value, so a new output value can be created using a slice of an input value. If a FieldMap object contains multiple input fields from the same table or feature class, each record's values are merged using the mergeRule property. This is a convenient way to join values, such as a street name that is held in one field and a street type that is held in another, for example, Eureka and Street. The joinDelimiter property of FieldMap is used if the mergeRule value Join is specified. Any set of characters, such as a space, can be used as a delimiter. In the above example, this would create a value of Eureka Street.
Property |
Explanation |
---|---|
inputFieldCount |
The number of defined input fields. |
joinDelimiter |
A string value used to separate input values from the same table if the output field type is string and the mergeRule is Join. |
mergeRule |
Defines how values from two or more fields from the same input table are merged into a single output value. Valid choices are as follows:
|
outputField |
The properties of the output field are either set or returned in a field object. |
Method |
Explanation |
---|---|
addInputField(table_dataset, field_name, {start_position}, {end_position}) |
Adds a field to the list of input fields by specifying the name, including the path to the field's input table or feature class and the name of the field, as well as the start and end position of the field value, if the input value is from a text field. |
findInputFieldIndex (table_dataset, field_name) |
Returns the index position of a specific field within the FieldMap's list of input fields. |
getEndTextPosition(index) |
Returns the position within the input field value that will be used to end the new output value. This property is only used when the input field type is text. |
getInputFieldName(index) |
Returns the field name for a specific input field. |
getInputTableName(index) |
Returns the table name for a specific input field. |
getStartTextPosition(index) |
Returns the position within the input field value that will be used to start the new output value. This property is only used when the input field type is text. |
removeAll() |
Deletes the contents of the FieldMap's list of input fields. |
removeInputField(index) |
Removes an input field from the FieldMap's list of input fields. |
setEndTextPosition(index, end_position) |
Defines the value indicating the last character position of the input value used to define the new output value. This property is only used when the input field type is text. |
setStartTextPosition(index, start_position) |
Defines the value indicating the first character position of the input value used to define the new output value. This property is only used when the input field type is text. |
The FieldMappings object is a collection of FieldMap objects, and it is used as the parameter value for tools that perform field mapping, such as Merge. The easiest way to work with these objects is to first create a FieldMappings object, then initialize its FieldMap objects by adding the input feature classes or tables that are to be combined. Once all inputs are provided, the FieldMappings object will contain one FieldMap object, or output field, for each unique field name from all the inputs. This list can be modified by adding new fields, altering the properties and/or contents of an output field, or removing any unwanted output fields.
Property |
Explanation |
---|---|
fieldCount |
The number of output fields. |
fieldValidationWorkspace |
The workspace type defines the rules for attribute field naming. These rules are used when determining the output field names, which are based on the names of the input fields from the input tables or feature classes. For example, a file system workspace that contains shapefiles may only have field names with a maximum length of 10 characters. |
fields |
A list of field objects. Each field object represents the properties of each output field. |
Method |
Explanation |
---|---|
addFieldMap(field_map) |
Adds a new FieldMap object that will define a new output field |
addTable(table_dataset) |
Specifies a table or feature class whose fields will be used to define the output fields |
exportToString() |
Saves the contents of the FieldMappings objects to a string value |
findFieldMapIndex(field_map_name) |
Using the name of the output field, returns the position of the FieldMap object for the field within the list of FieldMap objects that define the output fields |
getFieldMap(index) |
Returns a FieldMap object from the list of output fields using the index position of the FieldMap within that list |
loadFromString() |
Populates the contents of the FieldMappings object using a string definition of a FieldMappings object |
removeAll() |
Deletes the contents of the FieldMap list so that no output fields are defined |
removeFieldMap(index) |
Removes an output field in the list of FieldMap objects that define the output fields |
replaceFieldMap(index, value) |
Replaces an existing output field in the list of FieldMap objects that define the output fields using a new FieldMap object |
In the following example, a number of feature classes containing U.S. census data will be merged to form a new feature class. One of the input attributes found in all the inputs is a numeric field, STFID. This 15-digit value is a unique identifier for all census blocks for the United States. The value can be broken into four components. The first two digits provide the state code, the next three indicate the county, the following six identify the census tract, and the last four identify the census block. The value 360899912001006 represents the census block (1006) containing the State University of New York at Potsdam in upstate New York (36), within census tract 991200 of the county of St. Lawrence (089). The script sample will merge these feature classes together and also create two new fields, TRACTID and BLOCKID, because the input data only has the STFID attribute. To do this, the FieldMappings object is initialized using the addTable method to enter each input. Then the default FieldMappings object is modified by creating two new FieldMap objects, populating their properties, and adding them to the FieldMappings object.
import arcpy from arcpy import env env.workspace = "C:/Data/CityBlocks.gdb" outfc = "C:/Data/CityBlocks.gdb/AllBlocks" # Each of the input Feature classes has an STFID, which is the # combination of the Tract ID and Block ID for each block. # Separate these values out from this field into two new # fields, TRACTID and BLOCKID. # # Create a fieldmappings and two new fieldmaps. # fieldmappings = arcpy.FieldMappings() fldmap_TRACTID = arcpy.FieldMap() fldmap_BLOCKID = arcpy.FieldMap() # List all the feature classes in the workspace that start with # 'block' in their name and are of polygon feature type. # fcs = arcpy.ListFeatureClasses("block*", "Polygon") # Create a value table that will hold the input feature classes to Merge # vTab = arcpy.ValueTable() for fc in fcs: # Adding a table is the fast way to load all the fields from the # input into fieldmaps held by the fieldmappings object. # fieldmappings.addTable(fc) # In this example also create two fieldmaps by 'chopping up' # an input field. Feed the chopped field into the new fieldmaps. # fldmap_TRACTID.addInputField(fc, "STFID") fldmap_BLOCKID.addInputField(fc, "STFID") # Populate the input value table with feature classes # vTab.addRow(fc) # Set the starting and ending position of the fields going into the # TractID fieldmap. This is the location in the STFID field where the # TractID falls. # for x in range(0, fldmap_TRACTID.inputFieldCount): fldmap_TRACTID.setStartTextPosition(x, 5) fldmap_TRACTID.setEndTextPosition(x, 10) # Set the Name of the Field output from this field map. # fld_TRACTID = fldmap_TRACTID.outputField fld_TRACTID.name = "TRACTID" fldmap_TRACTID.outputField = fld_TRACTID # Set the starting and ending position of the fields going into the # BlockID fieldmap. This is the location in the STFID field where the # blockID falls. # for x in range(0, fldmap_BLOCKID.inputFieldCount): fldmap_BLOCKID.setStartTextPosition(x, 11) fldmap_BLOCKID.setEndTextPosition(x, 16) # Set the Name of the Field output from this field map. # fld_BLOCKID = fldmap_BLOCKID.outputField fld_BLOCKID.name = "BLOCKID" fldmap_BLOCKID.outputField = fld_BLOCKID # Add the custom fieldmaps into the fieldmappings object. # fieldmappings.addFieldMap(fldmap_TRACTID) fieldmappings.addFieldMap(fldmap_BLOCKID) # Run the Merge tool. # arcpy.Merge_management(vTab, outfc, fieldmappings)
The next example shows how to modify a FieldMap object after it has been created using the addTable method of the FieldMappings object. This is important when the inputs have fields with different names but logically contain the same values.
import arcpy outfc = "C:/data/CityData.gdb/AllBlocks" # Want to merge these two feature classes together. Have a field # that has the same content but the names are slightly different: # Blocks1 has TRACT2000 and Blocks2 TRACTCODE. Name the output # the same as Blocks1. # fc1 = "C:/data/CityData.gdb/Blocks1" fc2 = "C:/data/CityData.gdb/Blocks2" # Create a new fieldmappings and add the two input feature classes. # fieldmappings = arcpy.FieldMappings() fieldmappings.addTable(fc1) fieldmappings.addTable(fc2) # First get the TRACT2000 fieldmap. Then add the TRACTCODE field # from Blocks2 as an input field. Then replace the fieldmap within # the fieldmappings object. # fieldmap = fieldmappings.getFieldMap(fieldmappings.findFieldMapIndex("TRACT2000")) fieldmap.addInputField(fc2, "TRACTCODE") fieldmappings.replaceFieldMap(fieldmappings.findFieldMapIndex("TRACT2000"), fieldmap) # Remove the TRACTCODE fieldmap. # fieldmappings.removeFieldMap(fieldmappings.findFieldMapIndex("TRACTCODE")) # Create a value table that will hold the inputs for Merge. # vTab = arcpy.ValueTable() vTab.addRow(fc1) vTab.addRow(fc2) # Run the Merge tool. # arcpy.Merge_management(vTab, outfc, fieldmappings)