What methods are available in ArcGIS 10.2 to randomly subset a selection of points. For example, in the attached screenshot I am interested in keeping 20% of the selected points and deleting the rest.
Answer
Here's a python function that will select random features in a layer based on percent, ignoring current selection:
def SelectRandomByPercent (layer, percent):
#layer variable is the layer name in TOC
#percent is percent as whole number (0-100)
if percent > 100:
print "percent is greater than 100"
return
if percent < 0:
print "percent is less than zero"
return
import random
fc = arcpy.Describe (layer).catalogPath
featureCount = float (arcpy.GetCount_management (fc).getOutput (0))
count = int (featureCount * float (percent) / float (100))
if not count:
arcpy.SelectLayerByAttribute_management (layer, "CLEAR_SELECTION")
return
oids = [oid for oid, in arcpy.da.SearchCursor (fc, "OID@")]
oidFldName = arcpy.Describe (layer).OIDFieldName
path = arcpy.Describe (layer).path
delimOidFld = arcpy.AddFieldDelimiters (path, oidFldName)
randOids = random.sample (oids, count)
oidsStr = ", ".join (map (str, randOids))
sql = "{0} IN ({1})".format (delimOidFld, oidsStr)
arcpy.SelectLayerByAttribute_management (layer, "", sql)
Copy/paste this into the python shell in ArcMap.
Then in the shell type SelectRandomByPercent ("layer", num)
, where layer
is the name of your layer, and num
is a whole number of your percent.
A variation to find a subset selection as asked:
def SelectRandomByPercent (layer, percent):
#layer variable is the layer name in TOC
#percent is percent as whole number (0-100)
if percent > 100:
print "percent is greater than 100"
return
if percent < 0:
print "percent is less than zero"
return
import random
featureCount = float (arcpy.GetCount_management (layer).getOutput (0))
count = int (featureCount * float (percent) / float (100))
if not count:
arcpy.SelectLayerByAttribute_management (layer, "CLEAR_SELECTION")
return
oids = [oid for oid, in arcpy.da.SearchCursor (layer, "OID@")]
oidFldName = arcpy.Describe (layer).OIDFieldName
path = arcpy.Describe (layer).path
delimOidFld = arcpy.AddFieldDelimiters (path, oidFldName)
randOids = random.sample (oids, count)
oidsStr = ", ".join (map (str, randOids))
sql = "{0} IN ({1})".format (delimOidFld, oidsStr)
arcpy.SelectLayerByAttribute_management (layer, "", sql)
Finally, one more variation to select a layer by a count, instead of a percent:
def SelectRandomByCount (layer, count):
import random
layerCount = int (arcpy.GetCount_management (layer).getOutput (0))
if layerCount < count:
print "input count is greater than layer count"
return
oids = [oid for oid, in arcpy.da.SearchCursor (layer, "OID@")]
oidFldName = arcpy.Describe (layer).OIDFieldName
path = arcpy.Describe (layer).path
delimOidFld = arcpy.AddFieldDelimiters (path, oidFldName)
randOids = random.sample (oids, count)
oidsStr = ", ".join (map (str, randOids))
sql = "{0} IN ({1})".format (delimOidFld, oidsStr)
arcpy.SelectLayerByAttribute_management (layer, "", sql)
No comments:
Post a Comment