0

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);
1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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