34

I have a feature class with over 2,000 features, and I need to make them all individual feature classes based on a field.

Is there a way to do this?

12 Answers 12

44

You may use the Split By Attributes tool:

Splits an input dataset by unique attributes

There are versions available for:

  • in ArcCatalog 10.6, Split By Attributes constantly generates individual .dbf tables, not individual feature classes. But, in ArcGIS Desktop 10.6, the same tool generates correctly individual shapefiles. I don't understand why, and got same outputs trying to set working directory to both folder or geodatabase. – maycca Nov 4 at 7:43
22

You can achieve this with a very simple model if you have ArcGIS 10.0 or higher.

Create a model with Feature Iterator where the group by field is the attribute you wish to select by then send the output to the copy features tool using inline substitution to ensure a unique file name. The model is shown below:

Model for extracting by attribute

16

I do not have access to ArcMap 10, only 9.3, but I expect that it won't be very different from this.

You can create a simple script in Python, that checks your attribute field for different values, and then, for each of them runs a SELECT operation to your original Shapefile.

If you are not familiar with python scripting, all you need to do is open you IDLE (the python GUI) create a new file, and copy the code below. After adapting the code for your my_shapefile, outputdir and my_attribute it should work.

# Script created to separate one shapefile in multiple ones by one specific
# attribute

# Example for a Inputfile called "my_shapefile" and a field called "my_attribute"
import arcgisscripting

# Starts Geoprocessing
gp = arcgisscripting.create(9.3)
gp.OverWriteOutput = 1

#Set Input Output variables
inputFile = u"C:\\GISTemp\\My_Shapefile.shp" #<-- CHANGE
outDir = u"C:\\GISTemp\\" #<-- CHANGE

# Reads My_shapefile for different values in the attribute
rows = gp.searchcursor(inputFile)
row = rows.next()
attribute_types = set([])

while row:
    attribute_types.add(row.my_attribute) #<-- CHANGE my_attribute to the name of your attribute
    row = rows.next()

# Output a Shapefile for each different attribute
for each_attribute in attribute_types:
    outSHP = outDir + each_attribute + u".shp"
    print outSHP
    gp.Select_analysis (inputFile, outSHP, "\"my_attribute\" = '" + each_attribute + "'") #<-- CHANGE my_attribute to the name of your attribute

del rows, row, attribute_types, gp

#END
13

Did you see Split Layer By Attributes tool updated for ArcMap 10 here? If it does not work you can use Split (Analysis) for your needs.

Splitting the Input Features creates a subset of multiple output feature classes. The Split Field's unique values form the names of the output feature classes. These are saved in the target workspace.

split

Example Code:

import arcpy
arcpy.env.workspace = "c:/data"
arcpy.Split_analysis("Habitat_Analysis.gdb/vegtype", "climate.shp", "Zone",
                     "C:/output/Output.gdb", "1 Meters")
  • The built-in Split tool works great for your purposes if you create an extent rectangle the same size as your polygons you wish to split. – ccn Jan 31 '13 at 16:25
  • Unless I'm misreading the question I think it is asking for a "Split By Attribute" rather than a "Split By Location". Split (Analysis) provides "Split By Location" functionality. The comment by @ccn here offers an interesting workaround which could perhaps be edited in as a "clarification" to this answer. – PolyGeo Dec 3 '14 at 6:39
  • I worry that the question describes Split By Attribute functionality and your answer is mostly about Split [By Geometry]. – PolyGeo Jul 27 '17 at 22:56
  • The link is broken – PolyGeo Jun 27 at 22:29
9

I used @AlexandreNeto's script and updated it for ArcGIS 10.x users. Mainly you now have to import "arcpy" instead of "arcgisscripting":

# Script created to separate one shapefile in multiple ones by one specific
# attribute

# Example for a Inputfile called "my_shapefile" and a field called "my_attribute"
import arcpy

#Set Input Output variables
inputFile = u"D:\DXF-Export\my_shapefile.shp" #<-- CHANGE
outDir = u"D:\DXF-Export\\" #<-- CHANGE

# Reads My_shapefile for different values in the attribute
rows = arcpy.SearchCursor(inputFile)
row = rows.next()
attribute_types = set([])

while row:
    attribute_types.add(row.my_attribute) #<-- CHANGE my_attribute to the name of your attribute
    row = rows.next()

# Output a Shapefile for each different attribute
for each_attribute in attribute_types:
    outSHP = outDir + each_attribute + u".shp"
    print outSHP
    arcpy.Select_analysis (inputFile, outSHP, "\"my_attribute\" = '" + each_attribute + "'")     #<-- CHANGE my_attribute to the name of your attribute

del rows, row, attribute_types

#END
6

This is an even easier way to do this... and it outputs into a GDB.

http://www.umesc.usgs.gov/management/dss/split_by_attribute_tool.html

download the tool from USGS, took me 3 minutes to do what i had been trying for 1 hour.

  • Thank you for the link! Works like a charm (and for version 10.2!) – WolverineTime Mar 26 '15 at 17:07
  • I tried this tool recently, and nothing happened when I executed it. I chose my feature, selected the field to select features by, selected an output location, hit OK and nothing happened. It just wouldn't "go"...am I missing something? Thanks! – rachel.passer May 28 '15 at 15:09
6

I know you can use an iterator in model builder, but if you prefer to use python here is something I came up with. Add the script to a toolbox with the parameters in order as Input shpfile, fields(multivalue,obtained from input), and workspace. This script will split the shapefile into multiple shapefiles based on the fields you select, and output them into a folder of your choice.

import arcpy, re

arcpy.env.overwriteOutput = True

Input = arcpy.GetParameterAsText(0)  
Flds = "%s" % (arcpy.GetParameterAsText(1)) 
OutWorkspace = arcpy.GetParameterAsText(2) 


myre = re.compile(";")
FldsSplit = myre.split(Flds)

sort = "%s A" % (FldsSplit[0])
rows = arcpy.SearchCursor(Input, "", "", Flds, sort)

for row in rows:
    var = []
    for r in range(len(FldsSplit)):
        var.append(row.getValue(FldsSplit[r]))
    Query = ''
    Name = ''
    for x in range(len(var)):
        if x == 0:
            fildz = FldsSplit[x]
            Name = var[x] + "_"
            Query += (""" "%s" = '%s'""" % (fildz, var[x]))
        if x > 0:
            fildz = FldsSplit[x]
            Name += var[x] + "_"
            Query += (""" AND "%s" = '%s' """ % (fildz, var[x]))
    OutputShp = OutWorkspace + r"\%s.shp" % (Name)
    arcpy.Select_analysis(Input, OutputShp, Query)
4

I have eventually got it working with SearchCursor and Select_analysis

arcpy.env.workspace = strInPath
# create a set to hold the attributes
attributes=set([])
# ---- create a list of feature classes in the current workspace ----
listOfFeatures = arcpy.SearchCursor(strInPath,"","",strFieldName,"")
for row in listOfFeatures:
    attributes.add(row.getValue(strFieldName))
    count=1
try:
    for row in attributes:
        stroOutputClass = strBaseName + "_" +str(count)# (str(row.getValue(strFieldName))).replace('/','_')
        strOutputFeatureClass = os.path.join(strOutGDBPath, stroOutputClass)
        arcpy.Select_analysis(strInPath,strOutputFeatureClass,strQueryExp)#"["+strFieldName+"]"+"='"+row+"'")
        count=count+1
    del attributes
except:
    arcpy.AddMessage('Error found')
3

I'm not familiar with the Iterate Feature Selection tools in ModelBuilder, but exporting just that as Python code indicate that they can be called using arcpy.

    # Created on: 2015-05-19 15:26:10.00000
#   (generated by ArcGIS/ModelBuilder)
# Description: 
# ---------------------------------------------------------------------------

# Import arcpy module
import arcpy

# Load required toolboxes
arcpy.ImportToolbox("Model Functions")


# Local variables:
Selected_Features = ""
Value = "1"

# Process: Iterate Feature Selection
arcpy.IterateFeatureSelection_mb("", "", "false")
3

You can use a Search Cursor to loop through individual features in a feature class and write just the geometries to unique feature classes. In this example, I use a feature class of the USA and export the states to new shapefiles:

import arcpy

# This is a path to an ESRI FC of the USA
states = r'C:\Program Files (x86)\ArcGIS\Desktop10.2\TemplateData\TemplateData.gdb\USA\states'
out_path = r'C:\temp'

with arcpy.da.SearchCursor(states, ["STATE_NAME", "SHAPE@"]) as cursor:
    for row in cursor:
        out_name = str(row[0]) # Define the output shapefile name (e.g. "Hawaii")
        arcpy.FeatureClassToFeatureClass_conversion(row[1], out_path, out_name)
  • I think the downside of this answer is that you do not carry through the attributes. I prefer an answer more like gis.stackexchange.com/a/152165/115 which will. – PolyGeo Sep 15 '16 at 22:52
  • Good point @PolyGeo, however, the upside is that this can be wrapped into other workflows that also require cursor operations. – Aaron Sep 16 '16 at 1:46
  • ... but so could using Select_analysis in place of FeatureClassToFeatureClass - it's only one line of code that would change. – PolyGeo Sep 16 '16 at 1:51
2

You can use a geometry token (SHAPE@) within Copy Features (Data Management) to export each feature.

import arcpy, os

shp = r'C:\temp\yourSHP.shp'
outws = r'C:\temp'

with arcpy.da.SearchCursor(shp, ["OBJECTID","SHAPE@"]) as cursor:
    for row in cursor:
        outfc = os.path.join(outws, "fc" + str(row[0]))
        arcpy.CopyFeatures_management(row[1], outfc)
2

In Arcpy, Cursors honor layer/TableView selections. According to Getting list of selected features in ArcGIS for Desktop using Python code?, you can simply iterate feature selections.

However if you want to make a selection using arcpy, use SelectLayerByAttribute_management tool.

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.