Find the maximum value of a band in an image collection (globally, across time)

google-earth-enginegoogle-earth-engine-javascript-api

I am interested in finding the minimum and maximum values of a value. For example, in the code below, I would be interested in the minimum temperature across dimensions of time and space (i.e., just a single float value, the lowest temperature across the globe from 2015-01-01 to 2018-12-31).

var startDate = '2015-01-01'
var endDate = '2019-01-01'
var dataset = ee.ImageCollection("ECMWF/ERA5/MONTHLY").filterDate(startDate, endDate)
print(dataset.select("mean_2m_air_temperature").min())

This code reduces the image collection to a single image that is the minimum in each pixel across the dimension of time. However, now I would like to find the lowest of those values. I cannot figure this out with reduceRegion, and I have also spent time trying to get it by converting the image to an array (following this post). This code is below and I think is really close, but I don't know how to extract the number (and have it no longer be an Image!).

var array = dataset.select("mean_2m_air_temperature").toArrayPerBand();
var min = array.select("mean_2m_air_temperature").arraySort().arraySlice({start: -1});
print(min)

Best Answer

Here's one way to do it. It's doing some redundant work, calculating the spatial min for the temporal max and vice versa. But since it's happening in a single reduceRegion() operation, I would think it's more efficient than splitting this up into two reduceRegion(), only calculating min for min and max for max. The output is two dictionaries, one for min values, one for max values, where the keys are the band names. If you're only interested in a subset of the bands, just select() the ones you're interested (before reducing).

var region = Map.getBounds(true)
var startDate = '2015-01-01'
var endDate = '2019-01-01'
var dataset = ee.ImageCollection("ECMWF/ERA5/MONTHLY").filterDate(startDate, endDate)
var minMax = ee.Feature(null,
  dataset
    .reduce(ee.Reducer.minMax())
    .reduceRegion({
      reducer: ee.Reducer.minMax(),
      geometry: region, 
      scale: 27830,
      maxPixels: 1e13
    })
)
var min = minMax
  .select(['.*_min_min'], dataset.first().bandNames())
  .toDictionary()
var max = minMax
  .select(['.*_max_max'], dataset.first().bandNames())
  .toDictionary()

print(min.getNumber('mean_2m_air_temperature'))

https://code.earthengine.google.com/79261210e8dcd5f2a26f0adea3cdb20c