Google Earth Engine – Calculating Standard Deviation for Percentiles Interval in Google Earth Engine

google-earth-enginespatial statisticszonal statistics

I'm working on a GEE script aiming to extract DEM-based elevation statistics for regions defined by polygons. Specifically, I want to obtain the mean, median, standard deviation, and min/max values of the lowest 10% in the elevation ranges of different regions defined by polygons. The mean is easy since GEE has a reducer just for this purpose; the following works fine:

// Calculate median of lowest 10% elevation of polygon region
var lowest10PercentMeanDict = alos_DEM.reduceRegion({
    reducer: ee.Reducer.intervalMean(0, 10),
    geometry: regionPolygon.geometry(),
    scale: 30
})

A similar approach should be possible to obtain median and min/max with the 'percentiles' reducer.

However, I could not figure out yet how obtain the standard deviation for the percentile ranges calculated by the two reducers.

Is it possible to retrieve the data collected by 'intervalMean' and 'percentiles' to use it as input for further processing steps? Or is there a workaround using e.g. 'histogram'? Finally, it would be really cool if it was possible to apply the 'combine' reducer with 'sharedInputs' activated to calculate all relevant statistics for the percentile interval in one step.

Best Answer

See here (https://code.earthengine.google.com/e4ff91012eea56af783eefbfee2ed40d) for an example.

First we calculate the elevation for which 10% of the pixels in an AOI are lower. Then we use this value to mask out all the higher elevation pixels. Finally we calculate the different stats you are interested in.

You could then repeat the first step and repeat the masking of the DEM to calculate the stats for other regions.

var DEM = dem.select('AVE');

var low_10 = DEM.reduceRegion({reducer: ee.Reducer.percentile([10]),
                                geometry: aoi,
                                bestEffort: true}).get('AVE');

var masked_DEM = DEM.updateMask(DEM.lte(ee.Number(low_10)));

Map.addLayer(masked_DEM.clip(aoi));

var reducer1 = ee.Reducer.mean();

var reducers = reducer1.combine({reducer2: ee.Reducer.median(), sharedInputs: true})
                       .combine({reducer2: ee.Reducer.max(), sharedInputs: true})
                       .combine({reducer2: ee.Reducer.min(), sharedInputs: true})
                       .combine({reducer2: ee.Reducer.stdDev(), sharedInputs: true});

var results = masked_DEM.reduceRegion({reducer: reducers,
                                geometry: aoi,
                                bestEffort: true});

print(results);