2

I'm using CHIRPS dataset to get daily precipitation images. My goal is to have one image per month representing monthly average for the entire period (1981-2021).

I actually managed to get what I need. But I'm sure my code is kind of a "dumb" code since I'm writing codes for each month. I'm sure I can have a more elegant coding using some sort of iteration/loop. Ideas?

//Import CHIRPS image collection.
var prec = ee.ImageCollection('UCSB-CHG/CHIRPS/DAILY')
  .select('precipitation');

// Creating a collection of monthly means for the period 1981-01-01 to 2022-01-01
// Use ee.Filter.calendarRange to filter by year and month
var jan = prec.filter(ee.Filter.calendarRange(1981,2021,'year'))
  .filter(ee.Filter.calendarRange(1,1,'month'));

var feb = prec.filter(ee.Filter.calendarRange(1981,2021,'year'))
  .filter(ee.Filter.calendarRange(2,2,'month'));

var mar = prec.filter(ee.Filter.calendarRange(1981,2021,'year'))
  .filter(ee.Filter.calendarRange(3,3,'month'));
  
var apr = prec.filter(ee.Filter.calendarRange(1981,2021,'year'))
  .filter(ee.Filter.calendarRange(4,4,'month'));
  
var may = prec.filter(ee.Filter.calendarRange(1981,2021,'year'))
  .filter(ee.Filter.calendarRange(5,5,'month'));
  
var jun = prec.filter(ee.Filter.calendarRange(1981,2021,'year'))
  .filter(ee.Filter.calendarRange(6,6,'month'));
  
var jul = prec.filter(ee.Filter.calendarRange(1981,2021,'year'))
  .filter(ee.Filter.calendarRange(7,7,'month'));
  
var aug = prec.filter(ee.Filter.calendarRange(1981,2021,'year'))
  .filter(ee.Filter.calendarRange(8,8,'month'));
  
var sep = prec.filter(ee.Filter.calendarRange(1981,2021,'year'))
  .filter(ee.Filter.calendarRange(9,9,'month'));
  
var oct = prec.filter(ee.Filter.calendarRange(1981,2021,'year'))
  .filter(ee.Filter.calendarRange(10,10,'month'));
  
var nov = prec.filter(ee.Filter.calendarRange(1981,2021,'year'))
  .filter(ee.Filter.calendarRange(11,11,'month'));
  
var dec = prec.filter(ee.Filter.calendarRange(1981,2021,'year'))
  .filter(ee.Filter.calendarRange(12,12,'month'));

// reduce image collections with mean()
var jan_mean = jan.mean();
var feb_mean = feb.mean();
var mar_mean = mar.mean();
var apr_mean = apr.mean();
var may_mean = may.mean();
var jun_mean = jun.mean();
var jul_mean = jul.mean();
var aug_mean = aug.mean();
var sep_mean = sep.mean();
var oct_mean = oct.mean();
var nov_mean = nov.mean();
var dec_mean = dec.mean();

var monthly_means = ee.ImageCollection.fromImages([
  jan_mean,
  feb_mean,
  mar_mean,
  apr_mean,
  may_mean,
  jun_mean,
  jul_mean,
  aug_mean,
  sep_mean,
  oct_mean,
  nov_mean,
  dec_mean
]);

EDIT: this is code is actually wrong. The CHIRPS data is in mm/day of precipitation. If I want the monthly mean for the whole period, I have to sum the daily precipitation of each month in each year and then average the summed Januaries of all years. The answer below is delivering the right results.

1 Answer 1

4

For this case, map month by month I think it's a better approach:

var pp_monthly = ee.List.sequence(0, (2021-1981)*12).map(function(n) {
  var start = ee.Date('1981-01-01').advance(n, 'month');
  var end = start.advance(1, 'month');
  return ee.ImageCollection('UCSB-CHG/CHIRPS/DAILY')
  .filterDate(start, end)
  .select('precipitation')
  .sum();
});

print(ee.ImageCollection(pp_monthly.flatten()));

By the way, map() is the sort of iteration you are looking for. A for loop won't work. Please check Client vs Server for more details. Many of the classical coding practices don't work with server-side functions.


Edit:

Adapted for monthly mean for the entire period using ee.Filter.calendarRange(start,end,field):

var start = '1981-01-01';
var end = '2021-12-31';

var pp_yearmon = ee.List.sequence(1,12).map(function(n) {
  return ee.ImageCollection('UCSB-CHG/CHIRPS/DAILY')
  .filterDate(start, end)
  .filter(ee.Filter.calendarRange(n,n,'month'))
  .select('precipitation')
  .sum().divide(2021-1981);
});

print(ee.ImageCollection(pp_yearmon.flatten()))
4
  • That's almost what I'm looking for. Except that with that mapping the mean() is calculated for every month of every year. As you can see in my code, the goal is to have 12 rasters in the collection, one for each month representing the average precipitation for the entire period - i.e., the January raster is the mean of the January month considering 1981-2021.
    – Jecogeo
    Jun 10, 2022 at 13:21
  • I just realized my calculations are wrong. The CHIRPS data is in mm/day of precipitation. If I want the monthly mean for the whole period, I have to sum the daily precipitation of each month in each year and then average the summed Januaries of all years. I'll try to do that to update my code
    – Jecogeo
    Jun 10, 2022 at 13:27
  • @Jecogeo sorry, I misunderstood the purpose. I edited for the initial idea and also I change to .sum. At the end you need to divide the output for getting the monthly mean in the period
    – aldo_tapia
    Jun 10, 2022 at 13:32
  • 1
    Great!! way more elegant!! thanks a lot!
    – Jecogeo
    Jun 10, 2022 at 14:39

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.