Grouped Reductions and Zonal Statistics

You can get statistics in each zone of an Image or FeatureCollection by using reducer.group() to group the output of a reducer by the value of a specified input. For example, to compute the total population and number of housing units in each state, this example groups the output of a reduction of a counties FeatureCollection as follows:

// Load a collection of US counties with census data properties.
var counties = ee.FeatureCollection('ft:1S4EB6319wWW2sWQDPhDvmSBIVrD3iEmCLYB7nMM');

// Compute sums of the specified properties, grouped by state name.
var sums = counties
  .filter(ee.Filter.and(
    ee.Filter.neq('Census 2000 Population', null),
    ee.Filter.neq('Census 2000 Housing Units', null)))
  .reduceColumns({
    selectors: ['Census 2000 Population', 'Census 2000 Housing Units', 'StateName'],
    reducer: ee.Reducer.sum().repeat(2).group({
      groupField: 2,
      groupName: 'state',
    })
});

// Print the resultant Dictionary.
print(sums);
    

The groupField argument is the index of the input in the selectors array that contains the codes by which to group, the groupName argument specifies the name of the property to store the value of the grouping variable. Since the reducer is not automatically repeated for each input, the repeat(2) call is needed.

To group output of image.reduceRegions() you can specify a grouping band that defines groups by integer pixel values. This type of computation is sometimes called "zonal statistics" where the zones are specified as the grouping band and the statistic is determined by the reducer. In the following example, change in nightlights in the United States is grouped by land cover category:

// Load a region representing the United States
var region = ee.Feature(
  ee.FeatureCollection('ft:1tdSwUL7MVpOauSgRzqVTOwdfy17KDbw-1d9omPw')
  .filter(ee.Filter.eq('Country', 'United States'))
  .first());

// Load MODIS land cover categories in 2001.
var landcover = ee.Image('MODIS/051/MCD12Q1/2001_01_01')
  // Select the IGBP classification band.
  .select('Land_Cover_Type_1');

// Load nightlights image inputs.
var nl2001 = ee.Image('NOAA/DMSP-OLS/NIGHTTIME_LIGHTS/F152001')
  .select('stable_lights');
var nl2012 = ee.Image('NOAA/DMSP-OLS/NIGHTTIME_LIGHTS/F182012')
  .select('stable_lights');

// Compute the nightlights decadal difference, add land cover codes.
var nlDiff = nl2012.subtract(nl2001).addBands(landcover);

// Grouped a mean reducer: change of nightlights by land cover category.
var means = nlDiff.reduceRegion({
  reducer: ee.Reducer.mean().group({
    groupField: 1,
    groupName: 'code',
  }),
  geometry: region.geometry(),
  scale: 1000,
  maxPixels: 1e8
});

// Print the resultant Dictionary.
print(means);
    

Note that in this example, the groupField is the index of the band containing the zones by which to group the output. The first band is index 0, the second is index 1, etc.

Send feedback about...

Google Earth Engine API