0

In ArcGIS Pro I have a continuous raster.

I want to calculate an upper and lower percentile value and apply to smooth out the range of values. For example applying the 90th percentile value to the top end, reducing the effects of extreme outlier values.

I have the below code in a Python notebook within ArcGIS Pro to determine percentiles:

import numpy as np

arr = arcpy.RasterToNumPyArray('raster_raste')
print(arr.max())
print(arr.min())
print(arr.mean())
p1 = np.percentile(arr,10)
p2 = np.percentile(arr,90)
p3 = np.percentile(arr,100)

The values I got for p1, p2 and p3 were 0, 0 and 83 respectively. The mean of the raster was 0.025. This indicated there could have been many zero's or noData values, so I used 'Extract by Attributes' to select all values above 1.

However applying the same code to the new filtered raster layer I still get the same percentiles and mean values.

How do I get the actual percentiles and apply them to the raster layer?

Ideally I would like something like below for rasters but I'm not sure the right code/tool to apply:

#use cursor to update the new rank field
with arcpy.da.UpdateCursor(input , ['population_density','PerRank']) as cursor:
    for row in cursor:
        if row[0] < p1:
            row[1] = 0  #rank 0
        elif p1 <= row[0] and row[0] < p2:
             row[1] = 1
        else:
             row[1] = 2

        cursor.updateRow(row)

1 Answer 1

0

Doesn't really matter what you do to the raster, NoData will be included in the numpy array. Just filter it out. Either work out what the NoData value is or tell RasterToNumPyArray to set the NoData elements to a specific value, e.g.

## Either figure out NoData value
nodata = arcpy.da.Describe(your_raster)["noDataValue"]
# or
nodata = arcpy.Raster(your_raster).noDataValue
arr = arcpy.RasterToNumPyArray('raster')


## Or specify a NoData value
nodata = -9999
arr = arcpy.RasterToNumPyArray('raster', nodata_to_value=nodata)

## Then filter your array for that nodata value
arr = arr[arr<nodata]

## Then calc your stats
p1 = np.percentile(arr,10)
p2 = np.percentile(arr,90)
p3 = np.percentile(arr,100)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.