I have a set of points. For each point, I want the values from a raster within a buffer radius around the point. The radius of the buffer can vary. Once I have these values, I compare them to a value from the point attributes. I'm checking to see if at least one value from the raster is +/- 1.0 from the point's value. I have figured out how to do this with ArcPy, however I have thousands of points and it takes about 30 seconds to run just 10 points. Is there a faster way to do this?
I'm running Python 3.11:
with arcpy.da.UpdateCursor(TestPts, fields, wclause) as cursor:
for row in cursor:
# Create a buffer polygon geometry around this point
geom = row[0]
buff = geom.buffer(thisbuffdist)
# Set the extent to just the buffer polygon
arcpy.env.extent = buff.extent
# Extract raster cells within the buffer
OutRasEBM = ExtractByMask(Ras, buff, 'INSIDE')
# Convert extracted Raster to numpy array
arr = arcpy.RasterToNumPyArray(OutRasEBM)
# Clear buff and OutRasEBM from memory
del buff, OutRasEBM
# Find if a value in the array is within 1 foot of pointvalue
pointvalue = row[1]
diffarr = arr - pointvalue
for rw in diffarr:
for x in rw:
if x > -1.0 and x < 1.0:
row[2] = 'P'
break
cursor.updateRow(row)
Try
with arcpy.da.UpdateCursor(TestPts, fields, wclause) as cursor:
for row in cursor:
geom = row[0]
buff = geom.buffer(thisbuffdist)
arcpy.env.extent = buff.extent
# Extract raster cells within the buffer based on attribute condition
expression = f"VALUE >= {row[1] - 1.0} AND VALUE <= {row[1] + 1.0}"
OutRasEBM = ExtractByAttributes(Ras, expression)
# Convert extracted Raster to numpy array
arr = arcpy.RasterToNumPyArray(OutRasEBM)
# Check if any value in the array meets the condition
if (arr > row[1] - 1.0).any() and (arr < row[1] + 1.0).any():
row[2] = 'P'
cursor.updateRow(row)
Here is a superior method that can be done in three tools that will process hundreds of points in a few seconds. I present it as a model so its easier to understand, and you can convert this to python if you so wish.
As a side note reviewing your code thisbuffdist never changes within the loop so your buffer distance is constant for the points, my logic follows this logic.
So here is some sample data, a green sample point and the background raster labelled with its cell values. The circle is showing a radius, in this case 100m to depict the neighbourhood.
The three step model is this:
The focal statistics tool is set to create a circular neighbourhood and extract the RANGE within that neighbourhood. This range value is passed through to the points and then I simply select all points with a range > 1.
Here is a screenshot showing 3 points selected whilst 1 remains unselected (dark blue) to prove that the logic works.