Coming from the programming in Earth Engine through the Code Editor, you will need to slightly adapt your scripts to be able to run in Python. For the bulk of your code, you will be using Earth Engine API's server-side objects and functions - which will be exactly the same in Python. You only need to make a few syntactical changes.
Here's the full list of differences.
First of all, you need to run the following cells to initialize the API and authorize your account. You must have a Google Cloud Project associated with your GEE account. Replace the cloud_project
with your own project from Google Cloud Console.
You will be prompted to allow the notebook to access your Google credentials to sign-in to the account and allow access to Google Drive and Google Cloud data. Once you approve, it will proceed to initialize the Earth Engine API. This step needs to be done just once per session.
import ee
cloud_project = 'spatialthoughts'
try:
ee.Initialize(project=cloud_project)
except:
ee.Authenticate()
ee.Initialize(project=cloud_project)
Python code doesn't use the 'var' keyword
javascript code:
var city = 'San Fransico'
var state = 'California'
print(city, state)
var population = 881549
print(population)
city = 'San Fransico'
state = 'California'
print(city, state)
population = 881549
print(population)
You can create Earth Engine objects using the ee
functions the same way.
s2 = ee.ImageCollection('COPERNICUS/S2_HARMONIZED')
geometry = ee.Geometry.Polygon([[
[82.60642647743225, 27.16350437805251],
[82.60984897613525, 27.1618529901377],
[82.61088967323303, 27.163695288375266],
[82.60757446289062, 27.16517483230927]
]])
Python doesn't use a semi-colon for line ending. To indicate line-continuation you need to use the \ character
javascript code:
var s2 = ee.ImageCollection('COPERNICUS/S2_HARMONIZED');
var filtered = s2.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 30))
.filter(ee.Filter.date('2019-02-01', '2019-03-01'))
.filter(ee.Filter.bounds(geometry));
filtered = s2 \
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 30)) \
.filter(ee.Filter.date('2019-02-01', '2019-03-01')) \
.filter(ee.Filter.bounds(geometry))
Instead of the function
keyword, Python uses the def
keyword. Also the in-line functions are defined using lambda
anonymous functions.
In the example below, also now the and
operator - which is capitalized as And
in Python version to avoid conflict with the built-in and
operator. The same applies to Or
and Not
operators. true
, false
, null
in Python are also spelled as True
, False
and None
.
javascript code:
function maskS2clouds(image) {
var qa = image.select('QA60')
var cloudBitMask = 1 << 10;
var cirrusBitMask = 1 << 11;
var mask = qa.bitwiseAnd(cloudBitMask).eq(0).and(
qa.bitwiseAnd(cirrusBitMask).eq(0))
return image.updateMask(mask)//.divide(10000)
.select("B.*")
.copyProperties(image, ["system:time_start"])
}
function addNDVI(image) {
var ndvi = image.normalizedDifference(['B8', 'B4']).rename('ndvi');
return image.addBands(ndvi);
}
def maskS2clouds(image):
qa = image.select('QA60')
cloudBitMask = 1 << 10
cirrusBitMask = 1 << 11
mask = qa.bitwiseAnd(cloudBitMask).eq(0).And(
qa.bitwiseAnd(cirrusBitMask).eq(0))
return image.updateMask(mask) \
.select("B.*") \
.copyProperties(image, ["system:time_start"])
def addNDVI(image):
ndvi = image.normalizedDifference(['B8', 'B4']).rename('ndvi')
return image.addBands(ndvi)
withNdvi = filtered \
.map(maskS2clouds) \
.map(addNDVI)
Named arguments to Earth Engine functions need to be in quotes. Also when passing the named arguments as a dictionary, it needs to be passed using the **
keyword.
javascript code:
var composite = withNdvi.median();
var ndvi = composite.select('ndvi');
var stats = ndvi.reduceRegion({
reducer: ee.Reducer.mean(),
geometry: geometry,
scale: 10,
maxPixels: 1e10
})
composite = withNdvi.median()
ndvi = composite.select('ndvi')
stats = ndvi.reduceRegion(**{
'reducer': ee.Reducer.mean(),
'geometry': geometry,
'scale': 10,
'maxPixels': 1e10
})
The print()
function syntax is the same. But you must remember that in the Code Editor when you cann print
, the value of the server object is fetched and then printed. You must do that explicitely by calling getInfo()
on any server-side object.
javascript code:
print(stats.get('ndvi')
print(stats.get('ndvi').getInfo())
The syntax for defining in-line functions is also slightly different. You need to use the lambda
keyword.
javascript code:
var myList = ee.List.sequence(1, 10);
var newList = myList.map(function(number) {
return ee.Number(number).pow(2);
print(newList);
myList = ee.List.sequence(1, 10)
newList = myList.map(lambda number: ee.Number(number).pow(2))
print(newList.getInfo())
Take the Javascript code snippet below and write the equiavalent Python code in the cell below.
\
.getInfo()
on the objectThe correct code should print the value 30.
var geometry = ee.Geometry.Point([77.60412933051538, 12.952912912328241]);
var s2 = ee.ImageCollection('COPERNICUS/S2_HARMONIZED');
var filtered = s2.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 30))
.filter(ee.Filter.date('2019-01-01', '2020-01-01'))
.filter(ee.Filter.bounds(geometry));
print(filtered.size());