Split Layer by Attribute Values GP Tool

Idea created by mbabinski1988 on Jun 22, 2016
    • mbabinski1988
    • rborchert
    • gizagui
    • nisha
    • cdevault1

    It would be useful to have a geoprocessing tool that will export features in an input layer to a specified workspace based on their unique attribute values. There is already the Split (Analysis) tool, which will accomplish this based on spatial location.


    Based on GeoNet and StackExchange conversations that I have seen recently, this would get some use. I love it when Esri adds really basic tools to the ArcToolbox so folks don't have to re-invent the wheel! Here is my custom geoprocessing script that mimics the behavior of what I am talking about. These are also attached to the post:


    # split_layer_by_attribute.py
    # Author: Micah Babinski
    # Date: 6/22/2016

    # import required modules
    import arcpy, os

    # get user parameters
    input_layer = arcpy.GetParameterAsText(0) # feature layer or feature class
    split_field = arcpy.GetParameterAsText(1) # field list
    output_workspace = arcpy.GetParameterAsText(2) # workspace
    ignore_selection = arcpy.GetParameterAsText(3) # boolean, decides whether to clear the selection first

    # environment setting
    arcpy.env.overwriteOutput = True

    # get the field type
    for f in arcpy.ListFields(input_layer):
        if f.name.upper() == split_field.upper():
            field_type = f.type

    # define a function to get unique values
    def GetUniqueFieldValues(table, field):
        Retrieves and prints a list of unique values in a user-specified field

            table (str): path or name of a feature class, layer, table, or table view
            field (str): name of the field for which the user wants unique values

            uniqueValues (list): a list of the unique values in the field

        # get the values
        with arcpy.da.SearchCursor(table, [field]) as cursor:
            return sorted({row[0] for row in cursor})

    # clear features if the user selected that option
    if str(ignore_selection) == "true":
        arcpy.SelectLayerByAttribute_management(input_layer, "CLEAR_SELECTION")

    # get the unique values of the specified field
    unique_values = GetUniqueFieldValues(input_layer, split_field)

    # iterate through the unique values, exporting each as a feature class to the output workspace
    for v in unique_values:
        arcpy.AddMessage("Splitting for attribute value " + str(v))
        if field_type == "String":
            exp = """"{0}" = '{1}'""".format(split_field, v)
            exp = """"{0}" = {1}""".format(split_field, v)
        output_name = os.path.join(output_workspace, arcpy.ValidateTableName(arcpy.Describe(input_layer).baseName + "_" + str(v), output_workspace))
        arcpy.Select_analysis(input_layer, output_name, exp)