I am trying to run a python script to select 5 random points in an attribute table and to loop through every 100 points to do this. When I run the function SelectRandomByCOunt within a python shell, it works perfectly fine but I am trying to embed it in this For loop and it doesnt work. I keep getting this error mesg:

ExecuteError: Failed to execute. Parameters are not valid.
The value cannot be a feature class
ERROR 000840: The value is not a Raster Layer.
ERROR 000840: The value is not a Mosaic Layer.
Failed to execute (SelectLayerByAttribute).

The code

import arcpy
import os
from arcpy import env

# path name of the feature class
ws = r"S:\Venu\APWRAGOEAProject\APWRAGOEA.gdb"
fcname = r"PracticePythonCode"
fc = os.path.join(ws, fcname)

# replace 'xxx' with file path

# get count of features
num = arcpy.GetCount_management(fc)
print("There are "+str(num)+ " rows in your feature class.")

# start counters
count = 0
next100 = 1

with arcpy.da.SearchCursor(fc, ['OBJECTID']) as scursor:  ## column 1 name [0], column 2 name [1]

      for srow in scursor: # iterate through rows

        if count < (next100 * 100):
                      col1 = srow[0] ## grab value from column 1

      # do processing of these 100 records here using col1, col2 variables
                      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"
                                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)

                      SelectRandomByCount (fc,5)

                      # increase count by 1
                      count = count + 1


              # move to next group of 100 
                next100 = next100 + 1

del srow, scursor
  • 2
    Why is def SelectRandomByCount(Variable1,Variable2) inside your main?? In SelectLayerByAttribute your 2nd argument should be 'NEW_SELECTION' not an empty string, see resources.arcgis.com/en/help/main/10.2/index.html#//… for more info but that shouldn't raise that error unless S:\Venu\APWRAGOEAProject\APWRAGOEA.gdb\PracticePythonCode doesn't exist, use arcpy.Exists here. When you're using a with block for your arcpy.da cursor you don't del row, cursor objects, that's managed by the with; also for portability SearchCursor(fc, 'OID@') is more universal. – Michael Stimson Feb 13 '20 at 23:48
  • Thank you for your reply! I have the feature class defined in my .gdb. I am not python savvy for starters :( So I found this SelectByRandomCount code on stack exchange to select random set of points out of a huge dataset but then I wanted to only select out of a certain number of points and then select from the next set as an iteration in the table so I tried to embed this code inside a For loop. – PrabhaV Feb 14 '20 at 0:00
  • I got the function from here: gis.stackexchange.com/questions/78251/… – PrabhaV Feb 14 '20 at 0:03
  • That is a good example to start from but def Function(vars) by convention appears outside of the main (see w3schools.com/python/python_functions.asp for some basics) otherwise the function is being created and destroyed for each iteration. Procedural languages either prefer or insist on having the functions before the main. Another 'gotcha' is that functions scope their own variables, if you want to use a variable defined on the main level you need to implicitly specify that with the global statement otherwise you'll have the name defined twice but inaccessible outside scope. – Michael Stimson Feb 14 '20 at 0:31
  • BTW This conundrum sounded familiar, I've answered a similar question gis.stackexchange.com/questions/342907/… previously, though the situation was more complex but might be worth a look; it's only the selection function though, not the implementation in the main. – Michael Stimson Feb 14 '20 at 0:42

As the exception states, SelectLayerByAttribute_management expects a layer (which is not the same thing as feature class -fc variable in your case, that you are passing, which is just the data) and you have to create one before passing into the def. If you use Make Feature Layer tool to create a layer just before SelectRandomByCount call and pass this layer into your def call, e.g., SelectRandomByCount ("SayMyLayer",5), your code should run fine. However, there are many lingering parts in your code which is not related to the error that you receive!

  • Thank you it worked! I did this: # path name of the feature class fc = r'S:\Venu\APWRAGOEAProject\APWRAGOEA.gdb\PracticePythonCode' # Make a layer from the feature class arcpy.MakeFeatureLayer_management(fc,"fc_lyr") SelectRandomByCount ("fc_lyr",5) – PrabhaV Feb 14 '20 at 1:00

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.