1

I want to obtain a monthly-year time series of the NDVI inside certain region defined by a polygon. I think I could made it using JavaScript. But I would like to translate to the Python API. I'm a bit confused using nested functions in JavaScript and much more translating them to Python.

Here is my JavaScript code:

// Any region of the world
var polygon = ee.Geometry.Polygon([112.0, 1.0,
                                   112.0, 1.5,
                                   112.5, 1.5,
                                   112.5, 1.0,
                                   112.0, 1.0]);
Map.addLayer(polygon, {}, 'polygon');
Map.centerObject(polygon);

var startDate = '2001-01-01'
var endDate = '2002-12-31'

var modisNDVI = ee.ImageCollection('MODIS/MOD09GA_006_NDVI')
            .select('NDVI')
            .filterDate(startDate, endDate);

var months = ee.List.sequence(1, 12);
var years = ee.List.sequence(ee.Number(ee.Date(startDate).get("year")), 
                             ee.Number(ee.Date(endDate).get("year")));

// Map filtering and reducing across year-month combinations and convert to ImageCollection
var modis_YrMo = ee.ImageCollection.fromImages(
  years.map(function (y) {
        return months.map(function (m) {
            return modisNDVI
              .filter(ee.Filter.calendarRange(y, y, 'year'))
              .filter(ee.Filter.calendarRange(m, m, 'month'))
              .mean()
              .set('year',y)
              .set('month',m)
        });
    }).flatten());

var regionNDVI = function(image) {
  var ndvi = image.select("NDVI");
  var monthlyNDVI = ndvi.reduceRegion({
                        reducer: ee.Reducer.mean(), 
                        geometry: polygon, 
                        scale: 250,
                        });
      return image.set(monthlyNDVI);
};

var finalNDVI = modis_YrMo.map(regionNDVI)
print(finalNDVI, "finalNDVI")

In Python I would start with the following code:

import ee
import pandas as pd  # I want to export the results to a DataFrame

ee.Initialize()

# Any region of the world
polygon = ee.Geometry.Polygon([112.0, 1.0,
                               112.0, 1.5,
                               112.5, 1.5,
                               112.5, 1.0,
                               112.0, 1.0])
startDate = '2001-01-01'
endDate = '2002-12-31'

modisNDVI = (ee.ImageCollection('MODIS/MOD09GA_006_NDVI')
             .select('NDVI')
             .filterDate(startDate, endDate))

months = ee.List.sequence(1, 12)
years = ee.List.sequence(ee.Number(ee.Date(startDate).get("year")), 
                         ee.Number(ee.Date(endDate).get("year")))

Firstly, I don't know how to translate modis_YrMo and modis_YrMo functions to Python.

Can you help me with that?

Secondly, this works for one region/polygon, but how could I adapt the Python script to extract the mean NDVI of several regions/polygons?

I don't know how to do it with JavaScript either but I'd like to do it directly in Python

And finally, how can I finally export the monthly NDVI to a Pandas DataFrame?

Using JavaScript I would try to do it using Export.table.toDrive() or ui.Chart.image.series() and then exporting the chart or the .csv from the chart.

1 Answer 1

2

A good approach (based on a personal question, similar to this one) is mapping over month value, adding one month for each iteration.

Since you want a dataframe output, I see no need to use two different functions (see how the python function is defined here). Also, the function output is a dictionary with two keys (date and NDVI value). Then you get a dataframe easy to manipulate:

import ee
import pandas as pd

ee.Initialize()

# Any region of the world
polygon = ee.Geometry.Polygon([112.0, 1.0,
                               112.0, 1.5,
                               112.5, 1.5,
                               112.5, 1.0,
                               112.0, 1.0])
startDate = '2001-01-01'
endDate = '2002-12-31'

modisNDVI = ee.ImageCollection('MODIS/MOD09GA_006_NDVI').select('NDVI').filterDate(startDate, endDate)
    
def custom_fun(n):
    date = ee.Date(startDate).advance(n,'month')
    m = date.get("month")
    y = date.get("year")
    dic = ee.Dictionary({
        'Date':date.format('yyyy-MM')
    })
    
    tempNDVI = (modisNDVI.filter(ee.Filter.calendarRange(y, y, 'year'))
                .filter(ee.Filter.calendarRange(m, m, 'month'))
                .mean()
                .reduceRegion(
                    reducer = ee.Reducer.mean(),
                    geometry = polygon,
                    scale = 250))
    return dic.combine(tempNDVI)

modis_YrMo = ee.List.sequence(0, 12*2-1).map(custom_fun)

dataframe = pd.DataFrame(modis_YrMo.getInfo())

At this point, we solved question 1 (python function adaptation) and 3 (data frame output). For apply this function over several polygons (question 2) use .reduceRegions:

(modisNDVI.filter(ee.Filter.calendarRange(y, y, 'year'))
 .filter(ee.Filter.calendarRange(m, m, 'month'))
 .mean()
 .reduceRegions(
     reducer = ee.Reducer.mean(),
     collection = polygons))
0

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