我想计算每个区域(月份和年份)的平均NDVI(管理员级别3,也称为woreda)。所以我的最终结果将如下所示:
regions year month NDVI
---------------------------------
region_1 2010 1 0.5
region_1 2010 2 -0.6
region_1 2010 3 0.7
region_1 2010 4 -0.3
region_1 2010 5 0.4
region_1 2010 6 -0.5
region_1 2010 7 0.5
region_1 2010 8 -0.7
region_1 2010 9 0.8
region_1 2010 10 -0.55
region_1 2010 11 -0.3
region_1 2010 12 -0.2
region_2 2010 1 0.5
region_2 2010 2 -0.6
region_2 2010 3 0.7
region_2 2010 4 -0.3
region_2 2010 5 0.4
region_2 2010 6 -0.5
region_2 2010 7 0.5
region_2 2010 8 -0.7
region_2 2010 9 0.8
region_2 2010 10 -0.55
region_2 2010 11 -0.3
region_2 2010 12 -0.2
... ... ... ...
我的代码基本上针对var modisNDVI中的预定区域执行此操作。但是,我希望我的代码能够在2010年到2015年之间做到这一点,每个地区每个月都要这样做。
如何在不编写更多for循环(经过多年和几个月的迭代)的情况下做到这一点?
是否应该使用reduceRegion或.map()来跳过(所有)for循环?
我尝试使用reduceRegion s ,但未能将其应用于imageCollection。
// import data
var region = ee.FeatureCollection("ft:1zRUOJL1LYCPJj-mjP6ZRx8sxYKNH8EwDw3EPP66K"),
modisNDVI = ee.ImageCollection("MODIS/MCD43A4_006_NDVI");
// Get NDVI
var modisNDVI = ee.ImageCollection(modisNDVI.filterDate('2015-01-01', '2015-06-01'));
var woredaNames = region.aggregate_array("HRpcode")
// do something so I can get monthly data for each year (2010-2015) for earch woreda (690)
// I don't want to write another for loop for the year and month what is a more optimized way?
// Processing all the 690 takes long, for this example I've used 10 woreda's
for (var woreda=0; woreda < 10 ;woreda++){
// Focus on one region:
var focusRegion = region.filter(ee.Filter.eq('system:index', String(woreda)));
// Clip modis image on focused region:
var focus_NDVI_clip = modisNDVI.mean().clip(focusRegion);
// aggregate mean over geometry from focused region:
var mean_dict = focus_NDVI_clip.reduceRegion({
reducer: ee.Reducer.mean(),
geometry: focusRegion.geometry(),
scale: 500,
});
// Append index to mean_dictionary and print it (eventually this should turn into a list):
var woreda_code = ee.List(woredaNames).get(woreda);
mean_dict = mean_dict.set('Woreda_code', ee.String(woreda_code));
print(mean_dict);}
答案 0 :(得分:2)
首先,您应该不惜一切代价避免在Earth Engine上使用for循环,它只会使系统陷入瘫痪,并且不利于所有人(请参阅此page上的“循环”部分)。您可以使用nested mapping遍历要素集合,然后在所有时间段内提取所需的信息:
// import data
var region = ee.FeatureCollection("ft:1zRUOJL1LYCPJj-mjP6ZRx8sxYKNH8EwDw3EPP66K"),
modisNDVI = ee.ImageCollection("MODIS/MCD43A4_006_NDVI");
var startDate = ee.Date('2010-01-01'); // set analysis start time
var endDate = ee.Date('2010-12-31'); // set analysis end time
// calculate the number of months to process
var nMonths = ee.Number(endDate.difference(startDate,'month')).round();
var result = region.map(function(feature){
// map over each month
var timeDict = ee.List.sequence(0,nMonths).map(function (n){
// calculate the offset from startDate
var ini = startDate.advance(n,'month');
// advance just one month
var end = ini.advance(1,'month');
// filter and reduce
var data = modisNDVI.filterDate(ini,end).mean().reduceRegion({
reducer: ee.Reducer.mean(),
geometry: feature.geometry(),
scale: 1000
});
// return zonal mean with a time key
return data.combine(ee.Dictionary({'time':ini}));
});
// return feature with a timeseries property and results
return feature.set('timeseries',timeDict);
});
// print to see if it is doing what we expect...
print(result.select(["HRpcode",'timeseries']));
// Export the data to a table for further analysis
Export.table.toDrive({
collection:result,
description:"tester",
fileFormat:"CSV",
selectors:["HRpcode","timeseries"]
})
链接到代码:https://code.earthengine.google.com/abf5eeb5c203310c11bf45c6714ae731
在此实现中,结果格式可能有点时髦,其结果是将字典作为属性的特征集合,而不是数组或表...但是,希望这可以给您所需的内容或为您提供的一种方法得到您所需要的。