TransWikia.com

Finding Percentiles from a List in Google Earth Engine

Geographic Information Systems Asked on November 14, 2021

I am using Soil Moisture data from the FLDAS model, and have reduced the data down to a list containing a series of means. These means are average Soil Moisture for the Kenyan dry season (January through March 1982-present).

I wish to find the 20th, 30th, and 45th percentile value from this list using the ee.Reducer.percentile() function, but I keep getting the following error:

"ComputedObject (Error) List.reduce: Input must be a scalar number."

Looking for any help/ advice on finding percentile values from a list of numbers. Here is the code I have been using:

//importing collection and defining boundary of interest
var boundary =ee.Geometry.Point(37.559794, 0.771817).buffer(10000);
var SM = ee.ImageCollection('NASA/FLDAS/NOAH01/C/GL/M/V001').select("SoilMoi00_10cm_tavg");

//years of interest
var years = ee.List.sequence(1982,2019);

//reducing to Short Dry season
var temp = ee.ImageCollection.fromImages(
  years.map(function(y){
      return SM
        .filter(ee.Filter.calendarRange(y, y, 'year'))
        .filter(ee.Filter.calendarRange(1, 3, 'month'))
        .mean()
        .set('Season', "Short Dry").set('year', y)
        ;
  }).flatten());
  print("Check Star/End Dates", temp);

//Finding mean pixel value of each yearly image (reduces to single number)
  var temp = temp.toBands();
  var temp = temp.reduceRegions({
      collection: boundary,  // the region over which values are sumamrized
      reducer: ee.Reducer.mean(),  // the summary statistic 
      scale:1000 }).first();

//Putting these numbers in a list
  var propNames = temp.propertyNames();
var list = propNames.map(function(image){
  return temp.get(image);
});

//Calculating 20th,30th,and 45th percentiles
var percentiles = list.reduce(ee.Reducer.percentile([20,30,45]));

print("Percentiles",percentiles);

One Answer

The reason that you get the error is that one of the properties of your feature is 'system:index', which is a string.

You can work around this problem by mapping over the feature collection output of reduceRegions. Then use toDictionary() and values(), which transform only the non-system properties to a list.

var temp = collection.toBands().reduceRegions({
      collection: boundary,  // the region over which values are sumamrized
      reducer: ee.Reducer.mean(),  // the summary statistic 
      scale: 1000 });
print('feature collection output output',temp);
// Map over the feature collection to get the percentiles for each geometry in the input collection
temp = temp.map(function(feat){
  var list = feat.toDictionary().values();
  var percentiles = list.reduce(ee.Reducer.percentile([20,30,45]));
  return ee.Feature(feat.geometry(), percentiles);
});
print(temp)

You will then have a feature collection output with percentiles for every feature in your input collection.

As you only presented one geometry, you probably easier of using redceRegion. I added a suggestion for that in the link.

Answered by Kuik on November 14, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP