공지사항:
2025년 4월 15일 전에 Earth Engine 사용을 위해 등록된 모든 비상업용 프로젝트는 Earth Engine 액세스를 유지하기 위해
비상업용 자격 요건을 인증해야 합니다.
함수형 프로그래밍 개념
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
함수형 프로그래밍 소개
Earth Engine은 병렬 처리 시스템을 사용하여 많은 머신에서 계산을 실행합니다. 이러한 처리를 지원하기 위해 Earth Engine은 참조 투명성 및 지연 평가와 같이 함수형 언어에서 일반적으로 사용되는 표준 기법을 활용하여 상당한 최적화 및 효율성 향상을 달성합니다.
함수형 프로그래밍을 절차형 프로그래밍과 구분하는 주요 개념은 부작용의 부재입니다. 즉, 작성하는 함수가 함수 외부의 데이터를 사용하거나 업데이트하지 않습니다. 아래 예에서 볼 수 있듯이 부작용이 없는 함수를 사용하여 문제를 해결할 수 있도록 문제를 재구성할 수 있습니다. 이러한 함수는 병렬로 실행하는 데 훨씬 적합합니다.
For 루프
Earth Engine에서는 for 루프를 사용하지 않는 것이 좋습니다. 각 요소에 독립적으로 적용할 수 있는 함수를 지정하는 map()
작업을 사용하여 동일한 결과를 얻을 수 있습니다. 이를 통해 시스템은 처리를 여러 머신에 분산할 수 있습니다.
아래 예에서는 숫자 목록을 가져와 map()
를 사용하여 각 숫자의 제곱이 포함된 다른 목록을 만드는 방법을 보여줍니다.
코드 편집기 (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 조건
절차형 프로그래밍 패러다임에 익숙한 신규 사용자가 겪는 또 다른 일반적인 문제는 Earth Engine에서 if/else 조건 연산자를 올바르게 사용하는 것입니다. API는 ee.Algorithms.If()
알고리즘을 제공하지만 map()
및 필터를 사용하는 더 기능적인 접근 방식을 사용하는 것이 좋습니다.
Earth Engine은
지연된 실행을 사용합니다. 즉, 표현식의 평가가 실현된 값이 실제로 필요할 때까지 지연됩니다. 경우에 따라 이러한 유형의 실행 모델은 ee.Algorithms.If()
문의 true 및 false 대안을 모두 평가합니다. 이로 인해 표현식과 표현식을 실행하는 데 필요한 리소스에 따라 추가 계산과 메모리 사용량이 발생할 수 있습니다.
위 예시의 변형을 해결하려고 한다고 가정해 보겠습니다. 여기서 작업은 홀수의 제곱만 계산하는 것입니다. 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()
의 좋은 예는 피보나치 수열을 만드는 것입니다. 여기서 계열의 각 숫자는 이전 두 숫자의 합입니다. iterate()
함수는 함수 (알고리즘)와 시작 값이라는 두 개의 인수를 사용합니다. 함수 자체는 반복의 현재 값과 이전 반복의 결과라는 두 값을 전달받습니다. 다음 예에서는 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의 지리 공간 기능을 소개합니다.
달리 명시되지 않는 한 이 페이지의 콘텐츠에는 Creative Commons Attribution 4.0 라이선스에 따라 라이선스가 부여되며, 코드 샘플에는 Apache 2.0 라이선스에 따라 라이선스가 부여됩니다. 자세한 내용은 Google Developers 사이트 정책을 참조하세요. 자바는 Oracle 및/또는 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."]]