Using Python Search Cursor results to Select Features by Attributes

I would like to preface this by saying that I am very new to python and its capabilities. So my problem is that while using the in_memory work space I encountered some limitations in querying the minimum value for a field. My workaround for this was to create a dictionary, then use a the search cursor to find the minimum distance. My method returns the results that I am looking for but I have not been able to incorporate these results into my selection. Below is a snippet of the code I am currently using:

# Process: Near arcpy.Near_analysis(newStationLayer, targetPoint, "", "NO_LOCATION", "NO_ANGLE", "") nearDist = {} with arcpy.da.SearchCursor(newStationLayer,("[email protected]","NEAR_DIST")) as cur: for row in cur: nearDist[row[0]] = row[1] arcpy.AddMessage("Near distances: %s"%str(nearDist)) ## arcpy.AddWarning(min(nearDist.iteritems(),key=operator.itemgetter)) lowestOID = min(nearDist,key=nearDist.get) arcpy.AddWarning(lowestOID) arcpy.SelectLayerByAttribute_management()

I always do this using a function that I originally found on This Site. It builds a where clause for you, and works with lists. It's nice, because it uses the add field delimiters function and therefore you dont have to wory about what type of data you are using (shapefile, fgdb, etc.). Just add this to your code somewhere and then call the function to to create your where clause.

def buildWhereClause(table, field, valueList): fieldDelimited = arcpy.AddFieldDelimiters(arcpy.Describe(table).path, field) fieldType = arcpy.ListFields(table, field)[0].type if str(fieldType) == 'String': valueList = ["'%s'" % value for value in valueList] whereClause = "%s IN(%s)" % (fieldDelimited, ', '.join(map(str, valueList))) return whereClause

When you need your where clause:

whereClause = buildWhereClause(newStationLayer, "OBJECTID", [lowestOID])

And then:

arcpy.SelectLayerByAttribute_management(newStationLayer, "NEW_SELECTION", whereClause)

I did the selection parameters from memory, if it's not quite right you should at least get the idea.

A really simple way to get the minimum value is to use TableToNumPyArray to convert your table to a numpy array then use numpy functions.

from arcpy.da import TableToNumPyArray import numpy na = TableToNumPyArray(newStationLayer, "NEAR_DIST") numpy.min(na['NEAR_DIST'])

You can combine this directly with SelectLayerByAttribute_manager.

from arcpy.da import TableToNumPyArray import numpy field = "NEAR_DIST" na = TableToNumPyArray(newStationLayer, field) arcpy.SelectLayerByAttribute_management(newStationLayer,{}" = {}".format(field, numpy.min(na[field])))

In that last statement, I am using the string format function to insert my field name into the where clause and to insert the results of callingnumpy.minon my table array. For example, if your minimum value was 80.0, the where clause would become'"NEAR_DIST" = 80.0'.
If you get the error:

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).

It means that newStationLayer is a direct reference to a feature class and not a layer that you can apply a selection to. You will have to add something like:

layer = arcpy.MakeFeatureLayer_management(newStationLayer) arcpy.SelectLayerByAttribute_management(layer,{}" = {}".format(field, numpy.min(na[field])))

I just had a chance to test this, and this is the right format for an in_memory where clause. Your reference tonewStationLayerneeds to be a reference to the layer in the map though and not a direct reference to the in_memory feature class! (Otherwise you will get the error I talked about above.arcpy.MakeFeatureLayer_managementwill add a new layer to the map using your in_memory feature class.)

Watch the video: 10 - Select by Location with Search Cursor Recap - ArcMap Scripting with Python and Arcpy (October 2021).