お知らせ:
2025 年 4 月 15 日より前に Earth Engine の使用を登録したすべての非商用プロジェクトは、Earth Engine へのアクセスを維持するために
非商用目的での利用資格を確認する必要があります。
関数型プログラミングのコンセプト
コレクションでコンテンツを整理
必要に応じて、コンテンツの保存と分類を行います。
関数型プログラミングの概要
Earth Engine は、並列処理システムを使用して、多数のマシンで計算を実行します。このような処理を可能にするため、Earth Engine は、参照透過性や遅延評価など、関数型言語で一般的に使用される標準的な手法を利用して、大幅な最適化と効率化を実現しています。
関数型プログラミングと手続き型プログラミングを区別する主な概念は、副作用がないことです。つまり、記述する関数は、関数の外部にあるデータに依存したり、そのデータを更新したりしません。以下の例でわかるように、副作用のない関数を使用して解決できるように問題を再構築できます。これは、並列実行に適しています。
For ループ
Earth Engine では for ループの使用は推奨されていません。各要素に個別に適用できる関数を指定する map()
オペレーションを使用しても、同じ結果が得られます。これにより、システムは処理をさまざまなマシンに分散できます。
次の例は、数値のリストを取得し、map()
を使用して各数値の 2 乗を含む別のリストを作成する方法を示しています。
コードエディタ(JavaScript)
// This generates a list of numbers from 1 to 10.
var myList = ee.List.sequence(1, 10);
// The map() operation takes a function that works on each element independently
// and returns a value. You define a function that can be applied to the input.
var computeSquares = function(number) {
// We define the operation using the EE API.
return ee.Number(number).pow(2);
};
// Apply your function to each item in the list by using the map() function.
var squares = myList.map(computeSquares);
print(squares); // [1, 4, 9, 16, 25, 36, 49, 64, 81]
If/Else 条件
手続き型プログラミング パラダイムに慣れている新規ユーザーが直面するもう 1 つの一般的な問題は、Earth Engine での if/else 条件演算子の適切な使用です。API は ee.Algorithms.If()
アルゴリズムを提供しますが、map()
とフィルタを使用するより機能的なアプローチが推奨されます。Earth Engine は
遅延実行を使用します。つまり、式の評価は、その実現値が実際に必要になるまで遅延されます。このタイプの実行モデルでは、ee.Algorithms.If()
ステートメントの true と false の両方の代替案が評価されることがあります。式と、その実行に必要なリソースによっては、計算とメモリ使用量が増加する可能性があります。
上記の例のバリエーションを解く場合を考えてみましょう。このバリエーションでは、奇数の 2 乗のみを計算します。if/else 条件を使用せずにこの問題を解決する関数型アプローチを以下に示します。
コードエディタ(JavaScript)
// The following function determines if a number is even or odd. The mod(2)
// function returns 0 if the number is even and 1 if it is odd (the remainder
// after dividing by 2). The input is multiplied by this remainder so even
// numbers get set to 0 and odd numbers are left unchanged.
var getOddNumbers = function(number) {
number = ee.Number(number); // Cast the input to a Number so we can use mod.
var remainder = number.mod(2);
return number.multiply(remainder);
};
var newList = myList.map(getOddNumbers);
// Remove the 0 values.
var oddNumbers = newList.removeAll([0]);
var squares = oddNumbers.map(computeSquares);
print(squares); // [1, 9, 25, 49, 81]
このパラダイムは、コレクションを扱う場合に特に適しています。条件に基づいてコレクションに別のアルゴリズムを適用する場合は、まず条件に基づいてコレクションをフィルタリングし、次に各サブセットに別の関数を map()
するのが望ましい方法です。これにより、システムはオペレーションを並列化できます。例:
コードエディタ(JavaScript)
// Import Landsat 8 TOA collection and filter to 2018 images.
var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA')
.filterDate('2018-01-01', '2019-01-01');
// Divide the collection into 2 subsets and apply a different algorithm on them.
var subset1 = collection.filter(ee.Filter.lt('SUN_ELEVATION', 40));
var subset2 = collection.filter(ee.Filter.gte('SUN_ELEVATION', 40));
// Multiply all images in subset1 collection by 2;
// do nothing to subset2 collection.
var processed1 = subset1.map(function(image) {
return image.multiply(2);
});
var processed2 = subset2;
// Merge the collections to get a single collection.
var final = processed1.merge(processed2);
print('Original collection size', collection.size());
print('Processed collection size', final.size());
累積イテレーション
各イテレーションの結果が後続のイテレーションで使用される順次オペレーションが必要になることがあります。Earth Engine には、このようなタスク用の iterate()
メソッドが用意されています。iterate()
は順次実行されるため、大規模なオペレーションでは処理が遅くなることに注意してください。map()
とフィルタを使用して目的の出力を得られない場合にのみ使用してください。
iterate()
の良いデモは、フィボナッチ数列の作成です。この数列では、各数値は前の 2 つの数値の合計です。iterate()
関数は、関数(アルゴリズム)と開始値の 2 つの引数を取ります。関数自体には、反復処理の現在の値と、前の反復処理の結果の 2 つの値が渡されます。次の例は、Earth Engine でフィボナッチ数列を実装する方法を示しています。
コードエディタ(JavaScript)
var algorithm = function(current, previous) {
previous = ee.List(previous);
var n1 = ee.Number(previous.get(-1));
var n2 = ee.Number(previous.get(-2));
return previous.add(n1.add(n2));
};
// Compute 10 iterations.
var numIteration = ee.List.repeat(1, 10);
var start = [0, 1];
var sequence = numIteration.iterate(algorithm, start);
print(sequence); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
JavaScript のコンセプトを十分に理解できたので、API チュートリアルで Earth Engine API の地理空間機能の概要を確認してください。
特に記載のない限り、このページのコンテンツはクリエイティブ・コモンズの表示 4.0 ライセンスにより使用許諾されます。コードサンプルは Apache 2.0 ライセンスにより使用許諾されます。詳しくは、Google Developers サイトのポリシーをご覧ください。Java は Oracle および関連会社の登録商標です。
最終更新日 2025-07-26 UTC。
[null,null,["最終更新日 2025-07-26 UTC。"],[[["\u003cp\u003eEarth Engine leverages functional programming principles, like referential transparency and lazy evaluation, for parallel processing and optimization.\u003c/p\u003e\n"],["\u003cp\u003eAvoid for-loops and if/else statements; utilize \u003ccode\u003emap()\u003c/code\u003e for parallel processing and filters for conditional operations on collections.\u003c/p\u003e\n"],["\u003cp\u003eUse \u003ccode\u003eiterate()\u003c/code\u003e for cumulative, sequential operations where each step depends on the previous, but note its potential performance limitations.\u003c/p\u003e\n"],["\u003cp\u003eFunctional programming in Earth Engine prioritizes side-effect-free functions for efficient distributed computation across its infrastructure.\u003c/p\u003e\n"],["\u003cp\u003eEarth Engine's deferred execution model impacts how \u003ccode\u003eee.Algorithms.If()\u003c/code\u003e statements are evaluated, potentially leading to unnecessary computations.\u003c/p\u003e\n"]]],[],null,["# Functional Programming Concepts\n\nIntroduction to functional programming\n--------------------------------------\n\nEarth Engine uses a parallel processing system to carry out computation across a large number of\nmachines. To enable such processing, Earth Engine takes advantage of standard techniques commonly\nused by functional languages, such as referential transparency and lazy evaluation, for significant\noptimization and efficiency gains.\n\nThe main concept that sets functional programming apart from procedural programming is *the\nabsence of side effects*. What it means is that the functions that you write doesn't rely on or\nupdate data that is outside of the function. As you will see in the examples below, it is possible\nto re-structure your problem so that it can be solved using functions without side-effects - which\nare much better suited to be executed in parallel.\n\n### For Loops\n\nThe use of for-loops is discouraged in Earth Engine. The same results can be achieved using a\n`map()` operation where you specify a function that\ncan be independently applied to each element. This allows the system to distribute the processing to\ndifferent machines.\n\nThe example below illustrates how you would take a list of numbers and create another list with\nthe squares of each number using `map()`:\n\n\n### Code Editor (JavaScript)\n\n```javascript\n// This generates a list of numbers from 1 to 10.\nvar myList = ee.List.sequence(1, 10);\n\n// The map() operation takes a function that works on each element independently\n// and returns a value. You define a function that can be applied to the input.\nvar computeSquares = function(number) {\n // We define the operation using the EE API.\n return ee.Number(number).pow(2);\n};\n\n// Apply your function to each item in the list by using the map() function.\nvar squares = myList.map(computeSquares);\nprint(squares); // [1, 4, 9, 16, 25, 36, 49, 64, 81]\n```\n\n### If/Else Conditions\n\nAnother common problem faced by new users who are used to procedural\nprogramming paradigm is the proper use of if/else conditional operators in Earth Engine. While, the API\ndoes provide a `ee.Algorithms.If()` algorithm, the use of it is strongly discouraged\nin favor of a more functional approach using `map()` and filters.\nEarth Engine uses [deferred execution](/earth-engine/guides/deferred_execution), which means that the evaluation of an expression is delayed until its\nrealized value is actually required. In some cases, this type of execution model will evaluate\nboth the true and false alternatives of an `ee.Algorithms.If()` statement. This can\nlead to extra computation and memory usage, depending on the expressions and the resources\nrequired to execute them.\n\nSay you want to solve a variant of the above example, where the task is to compute squares of\nonly odd numbers. A functional approach to solving this without if/else conditions, is demonstrated\nbelow:\n\n### Code Editor (JavaScript)\n\n```javascript\n// The following function determines if a number is even or odd. The mod(2)\n// function returns 0 if the number is even and 1 if it is odd (the remainder\n// after dividing by 2). The input is multiplied by this remainder so even\n// numbers get set to 0 and odd numbers are left unchanged.\nvar getOddNumbers = function(number) {\n number = ee.Number(number); // Cast the input to a Number so we can use mod.\n var remainder = number.mod(2);\n return number.multiply(remainder);\n};\n\nvar newList = myList.map(getOddNumbers);\n\n// Remove the 0 values.\nvar oddNumbers = newList.removeAll([0]);\n\nvar squares = oddNumbers.map(computeSquares);\nprint(squares); // [1, 9, 25, 49, 81]\n```\n\nThis paradigm is especially applicable when working with collections. If you wanted to apply\na different algorithm to the collection based on some conditions, the preferred way is to first\nfilter the collection based on the condition, and then `map()` a different function to\neach of the subsets. This allows the system to parallelize the operation. For example:\n\n\n### Code Editor (JavaScript)\n\n```javascript\n// Import Landsat 8 TOA collection and filter to 2018 images.\nvar collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA')\n .filterDate('2018-01-01', '2019-01-01');\n\n// Divide the collection into 2 subsets and apply a different algorithm on them.\nvar subset1 = collection.filter(ee.Filter.lt('SUN_ELEVATION', 40));\nvar subset2 = collection.filter(ee.Filter.gte('SUN_ELEVATION', 40));\n\n// Multiply all images in subset1 collection by 2;\n// do nothing to subset2 collection.\nvar processed1 = subset1.map(function(image) {\n return image.multiply(2);\n});\nvar processed2 = subset2;\n\n// Merge the collections to get a single collection.\nvar final = processed1.merge(processed2);\nprint('Original collection size', collection.size());\nprint('Processed collection size', final.size());\n```\n\n### Cumulative Iteration\n\nYou may need to do sequential operation, where the result of\neach iteration is used by the subsequent iteration. Earth Engine provides a `iterate()`\nmethod for such tasks. Remember that `iterate()` is executed in a sequential manner and\nhence will be slow for large operations. Use it only when you are not able to use `map()`\nand filters to achieve the desired output.\n\nA good demonstration of `iterate()` is for creation of [Fibonacci number](https://en.wikipedia.org/wiki/Fibonacci_number) sequence. Here, each\nnumber in the series is the sum of previous 2 numbers. The `iterate()` function takes 2\narguments, a function (algorithm) and a starting value. The function itself gets passed on 2 values,\nthe current value in the iteration, and the result of the previous iteration. The following example\ndemonstrates how to implement a fibonacci sequence in Earth Engine.\n\n### Code Editor (JavaScript)\n\n```javascript\nvar algorithm = function(current, previous) {\n previous = ee.List(previous);\n var n1 = ee.Number(previous.get(-1));\n var n2 = ee.Number(previous.get(-2));\n return previous.add(n1.add(n2));\n};\n\n// Compute 10 iterations.\nvar numIteration = ee.List.repeat(1, 10);\nvar start = [0, 1];\nvar sequence = numIteration.iterate(algorithm, start);\nprint(sequence); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]\n```\n\nNow that you have a good understanding of javascript concepts, you can see the [API Tutorial](/earth-engine/tutorials/tutorial_api_01) for an introduction to the geospatial functionality of the\nEarth Engine API."]]