公告:凡是在
2025 年 4 月 15 日前註冊使用 Earth Engine 的非商業專案,都必須
驗證非商業用途資格,才能繼續存取 Earth Engine。
陣列轉換
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
Earth Engine 支援陣列轉換,例如轉置、反向和偽反向。舉例來說,請考慮圖片時間序列的一般最小二乘法 (OLS) 迴歸。在以下範例中,我們將含有預測變數和回應頻帶的圖片轉換為陣列圖片,然後「求解」,以三種方式取得最小二乘係數估計值。首先,請組合圖片資料並轉換為陣列:
程式碼編輯器 (JavaScript)
// Scales and masks Landsat 8 surface reflectance images.
function prepSrL8(image) {
// Develop masks for unwanted pixels (fill, cloud, cloud shadow).
var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0);
var saturationMask = image.select('QA_RADSAT').eq(0);
// Apply the scaling factors to the appropriate bands.
var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2);
var thermalBands = image.select('ST_B.*').multiply(0.00341802).add(149.0);
// Replace the original bands with the scaled ones and apply the masks.
return image.addBands(opticalBands, null, true)
.addBands(thermalBands, null, true)
.updateMask(qaMask)
.updateMask(saturationMask);
}
// Load a Landsat 8 surface reflectance image collection.
var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
// Filter to get only two years of data.
.filterDate('2019-04-01', '2021-04-01')
// Filter to get only imagery at a point of interest.
.filterBounds(ee.Geometry.Point(-122.08709, 36.9732))
// Prepare images by mapping the prepSrL8 function over the collection.
.map(prepSrL8)
// Select NIR and red bands only.
.select(['SR_B5', 'SR_B4'])
// Sort the collection in chronological order.
.sort('system:time_start', true);
// This function computes the predictors and the response from the input.
var makeVariables = function(image) {
// Compute time of the image in fractional years relative to the Epoch.
var year = ee.Image(image.date().difference(ee.Date('1970-01-01'), 'year'));
// Compute the season in radians, one cycle per year.
var season = year.multiply(2 * Math.PI);
// Return an image of the predictors followed by the response.
return image.select()
.addBands(ee.Image(1)) // 0. constant
.addBands(year.rename('t')) // 1. linear trend
.addBands(season.sin().rename('sin')) // 2. seasonal
.addBands(season.cos().rename('cos')) // 3. seasonal
.addBands(image.normalizedDifference().rename('NDVI')) // 4. response
.toFloat();
};
// Define the axes of variation in the collection array.
var imageAxis = 0;
var bandAxis = 1;
// Convert the collection to an array.
var array = collection.map(makeVariables).toArray();
// Check the length of the image axis (number of images).
var arrayLength = array.arrayLength(imageAxis);
// Update the mask to ensure that the number of images is greater than or
// equal to the number of predictors (the linear model is solvable).
array = array.updateMask(arrayLength.gt(4));
// Get slices of the array according to positions along the band axis.
var predictors = array.arraySlice(bandAxis, 0, 4);
var response = array.arraySlice(bandAxis, 4);
Python 設定
請參閱「
Python 環境」頁面,瞭解 Python API 和如何使用 geemap
進行互動式開發。
import ee
import geemap.core as geemap
Colab (Python)
import math
# Scales and masks Landsat 8 surface reflectance images.
def prep_sr_l8(image):
# Develop masks for unwanted pixels (fill, cloud, cloud shadow).
qa_mask = image.select('QA_PIXEL').bitwiseAnd(int('11111', 2)).eq(0)
saturation_mask = image.select('QA_RADSAT').eq(0)
# Apply the scaling factors to the appropriate bands.
optical_bands = image.select('SR_B.').multiply(0.0000275).add(-0.2)
thermal_bands = image.select('ST_B.*').multiply(0.00341802).add(149.0)
# Replace the original bands with the scaled ones and apply the masks.
return (
image.addBands(optical_bands, None, True)
.addBands(thermal_bands, None, True)
.updateMask(qa_mask)
.updateMask(saturation_mask)
)
# Load a Landsat 8 surface reflectance image collection.
collection = (
ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
# Filter to get only two years of data.
.filterDate('2019-04-01', '2021-04-01')
# Filter to get only imagery at a point of interest.
.filterBounds(ee.Geometry.Point(-122.08709, 36.9732))
# Prepare images by mapping the prep_sr_l8 function over the collection.
.map(prep_sr_l8)
# Select NIR and red bands only.
.select(['SR_B5', 'SR_B4'])
# Sort the collection in chronological order.
.sort('system:time_start', True)
)
# This function computes the predictors and the response from the input.
def make_variables(image):
# Compute time of the image in fractional years relative to the Epoch.
year = ee.Image(image.date().difference(ee.Date('1970-01-01'), 'year'))
# Compute the season in radians, one cycle per year.
season = year.multiply(2 * math.pi)
# Return an image of the predictors followed by the response.
return (
image.select()
.addBands(ee.Image(1)) # 0. constant
.addBands(year.rename('t')) # 1. linear trend
.addBands(season.sin().rename('sin')) # 2. seasonal
.addBands(season.cos().rename('cos')) # 3. seasonal
.addBands(image.normalizedDifference().rename('NDVI')) # 4. response
.toFloat()
)
# Define the axes of variation in the collection array.
image_axis = 0
band_axis = 1
# Convert the collection to an array.
array = collection.map(make_variables).toArray()
# Check the length of the image axis (number of images).
array_length = array.arrayLength(image_axis)
# Update the mask to ensure that the number of images is greater than or
# equal to the number of predictors (the linear model is solvable).
array = array.updateMask(array_length.gt(4))
# Get slices of the array according to positions along the band axis.
predictors = array.arraySlice(band_axis, 0, 4)
response = array.arraySlice(band_axis, 4)
請注意,arraySlice()
會針對沿著 bandAxis
(1 軸) 指定的索引範圍,傳回時間序列中的所有圖片。此時,您可以使用矩陣代數學來解出 OLS 係數:
程式碼編輯器 (JavaScript)
// Compute coefficients the hard way.
var coefficients1 = predictors.arrayTranspose().matrixMultiply(predictors)
.matrixInverse().matrixMultiply(predictors.arrayTranspose())
.matrixMultiply(response);
Python 設定
請參閱「
Python 環境」頁面,瞭解 Python API 和如何使用 geemap
進行互動式開發。
import ee
import geemap.core as geemap
Colab (Python)
# Compute coefficients the hard way.
coefficients_1 = (
predictors.arrayTranspose()
.matrixMultiply(predictors)
.matrixInverse()
.matrixMultiply(predictors.arrayTranspose())
.matrixMultiply(response)
)
雖然這個方法可行,但效率不佳,而且會導致程式碼難以閱讀。更好的方法是使用 pseudoInverse()
方法 (matrixPseudoInverse()
適用於陣列圖片):
程式碼編輯器 (JavaScript)
// Compute coefficients the easy way.
var coefficients2 = predictors.matrixPseudoInverse()
.matrixMultiply(response);
Python 設定
請參閱「
Python 環境」頁面,瞭解 Python API 和如何使用 geemap
進行互動式開發。
import ee
import geemap.core as geemap
Colab (Python)
# Compute coefficients the easy way.
coefficients_2 = predictors.matrixPseudoInverse().matrixMultiply(response)
從可讀性和運算效率的角度來看,取得 OLS 係數的最佳方式是 solve()
(如果是陣列圖片,則為 matrixSolve()
)。solve()
函式會根據輸入內容的特性,決定如何最佳解決系統,並使用超定系統的偽逆矩陣、正方陣的逆矩陣,以及近似奇異矩陣的特殊技術:
程式碼編輯器 (JavaScript)
// Compute coefficients the easiest way.
var coefficients3 = predictors.matrixSolve(response);
Python 設定
請參閱「
Python 環境」頁面,瞭解 Python API 和如何使用 geemap
進行互動式開發。
import ee
import geemap.core as geemap
Colab (Python)
# Compute coefficients the easiest way.
coefficients_3 = predictors.matrixSolve(response)
如要取得多頻帶圖像,請將陣列圖像投影至較低維度的空間,然後將其扁平化:
程式碼編輯器 (JavaScript)
// Turn the results into a multi-band image.
var coefficientsImage = coefficients3
// Get rid of the extra dimensions.
.arrayProject([0])
.arrayFlatten([
['constant', 'trend', 'sin', 'cos']
]);
Python 設定
請參閱「
Python 環境」頁面,瞭解 Python API 和如何使用 geemap
進行互動式開發。
import ee
import geemap.core as geemap
Colab (Python)
# Turn the results into a multi-band image.
coefficients_image = (
coefficients_3
# Get rid of the extra dimensions.
.arrayProject([0]).arrayFlatten([['constant', 'trend', 'sin', 'cos']])
)
請檢查這三種方法的輸出內容,並觀察無論使用哪種解算器,係數的最終矩陣都相同。solve()
靈活且高效,因此是一般用途線性建模的絕佳選擇。
除非另有註明,否則本頁面中的內容是採用創用 CC 姓名標示 4.0 授權,程式碼範例則為阿帕契 2.0 授權。詳情請參閱《Google Developers 網站政策》。Java 是 Oracle 和/或其關聯企業的註冊商標。
上次更新時間:2025-07-25 (世界標準時間)。
[null,null,["上次更新時間:2025-07-25 (世界標準時間)。"],[[["\u003cp\u003eEarth Engine enables array transformations like transpose, inverse, and pseudo-inverse for advanced analysis, such as ordinary least squares (OLS) regression on image time series.\u003c/p\u003e\n"],["\u003cp\u003eUsers can convert image collections to arrays, extract predictors and responses, and apply matrix operations to derive regression coefficients.\u003c/p\u003e\n"],["\u003cp\u003eEarth Engine offers multiple methods for solving linear systems, with \u003ccode\u003esolve()\u003c/code\u003e being the most efficient and adaptable for various scenarios, including overdetermined systems and nearly singular matrices.\u003c/p\u003e\n"],["\u003cp\u003eArray images resulting from calculations can be transformed back into multi-band images for visualization and further analysis.\u003c/p\u003e\n"]]],["The content demonstrates ordinary least squares (OLS) regression on a Landsat 8 image time series using Earth Engine. Key actions include preparing images by masking and scaling, creating predictor and response variables (constant, trend, seasonal, and NDVI), and converting the collection to an array. OLS coefficients are then calculated using three methods: direct matrix operations, pseudo-inverse, and the `matrixSolve()` function. Finally, the coefficient array is projected and flattened into a multi-band image. `matrixSolve()` is highlighted as the most efficient and flexible method.\n"],null,["# Array Transformations\n\nEarth Engine supports array transformations such as transpose, inverse and pseudo-inverse.\nAs an example, consider an ordinary least squares (OLS) regression of a time series of\nimages. In the following example, an image with bands for predictors and a response is\nconverted to an array image, then \"solved\" to obtain least squares coefficients estimates\nthree ways. First, assemble the image data and convert to arrays:\n\n### Code Editor (JavaScript)\n\n```javascript\n// Scales and masks Landsat 8 surface reflectance images.\nfunction prepSrL8(image) {\n // Develop masks for unwanted pixels (fill, cloud, cloud shadow).\n var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0);\n var saturationMask = image.select('QA_RADSAT').eq(0);\n\n // Apply the scaling factors to the appropriate bands.\n var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2);\n var thermalBands = image.select('ST_B.*').multiply(0.00341802).add(149.0);\n\n // Replace the original bands with the scaled ones and apply the masks.\n return image.addBands(opticalBands, null, true)\n .addBands(thermalBands, null, true)\n .updateMask(qaMask)\n .updateMask(saturationMask);\n}\n\n// Load a Landsat 8 surface reflectance image collection.\nvar collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')\n // Filter to get only two years of data.\n .filterDate('2019-04-01', '2021-04-01')\n // Filter to get only imagery at a point of interest.\n .filterBounds(ee.Geometry.Point(-122.08709, 36.9732))\n // Prepare images by mapping the prepSrL8 function over the collection.\n .map(prepSrL8)\n // Select NIR and red bands only.\n .select(['SR_B5', 'SR_B4'])\n // Sort the collection in chronological order.\n .sort('system:time_start', true);\n\n// This function computes the predictors and the response from the input.\nvar makeVariables = function(image) {\n // Compute time of the image in fractional years relative to the Epoch.\n var year = ee.Image(image.date().difference(ee.Date('1970-01-01'), 'year'));\n // Compute the season in radians, one cycle per year.\n var season = year.multiply(2 * Math.PI);\n // Return an image of the predictors followed by the response.\n return image.select()\n .addBands(ee.Image(1)) // 0. constant\n .addBands(year.rename('t')) // 1. linear trend\n .addBands(season.sin().rename('sin')) // 2. seasonal\n .addBands(season.cos().rename('cos')) // 3. seasonal\n .addBands(image.normalizedDifference().rename('NDVI')) // 4. response\n .toFloat();\n};\n\n// Define the axes of variation in the collection array.\nvar imageAxis = 0;\nvar bandAxis = 1;\n\n// Convert the collection to an array.\nvar array = collection.map(makeVariables).toArray();\n\n// Check the length of the image axis (number of images).\nvar arrayLength = array.arrayLength(imageAxis);\n// Update the mask to ensure that the number of images is greater than or\n// equal to the number of predictors (the linear model is solvable).\narray = array.updateMask(arrayLength.gt(4));\n\n// Get slices of the array according to positions along the band axis.\nvar predictors = array.arraySlice(bandAxis, 0, 4);\nvar response = array.arraySlice(bandAxis, 4);\n```\nPython setup\n\nSee the [Python Environment](/earth-engine/guides/python_install) page for information on the Python API and using\n`geemap` for interactive development. \n\n```python\nimport ee\nimport geemap.core as geemap\n```\n\n### Colab (Python)\n\n```python\nimport math\n\n\n# Scales and masks Landsat 8 surface reflectance images.\ndef prep_sr_l8(image):\n # Develop masks for unwanted pixels (fill, cloud, cloud shadow).\n qa_mask = image.select('QA_PIXEL').bitwiseAnd(int('11111', 2)).eq(0)\n saturation_mask = image.select('QA_RADSAT').eq(0)\n\n # Apply the scaling factors to the appropriate bands.\n optical_bands = image.select('SR_B.').multiply(0.0000275).add(-0.2)\n thermal_bands = image.select('ST_B.*').multiply(0.00341802).add(149.0)\n\n # Replace the original bands with the scaled ones and apply the masks.\n return (\n image.addBands(optical_bands, None, True)\n .addBands(thermal_bands, None, True)\n .updateMask(qa_mask)\n .updateMask(saturation_mask)\n )\n\n\n# Load a Landsat 8 surface reflectance image collection.\ncollection = (\n ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')\n # Filter to get only two years of data.\n .filterDate('2019-04-01', '2021-04-01')\n # Filter to get only imagery at a point of interest.\n .filterBounds(ee.Geometry.Point(-122.08709, 36.9732))\n # Prepare images by mapping the prep_sr_l8 function over the collection.\n .map(prep_sr_l8)\n # Select NIR and red bands only.\n .select(['SR_B5', 'SR_B4'])\n # Sort the collection in chronological order.\n .sort('system:time_start', True)\n)\n\n\n# This function computes the predictors and the response from the input.\ndef make_variables(image):\n # Compute time of the image in fractional years relative to the Epoch.\n year = ee.Image(image.date().difference(ee.Date('1970-01-01'), 'year'))\n # Compute the season in radians, one cycle per year.\n season = year.multiply(2 * math.pi)\n # Return an image of the predictors followed by the response.\n return (\n image.select()\n .addBands(ee.Image(1)) # 0. constant\n .addBands(year.rename('t')) # 1. linear trend\n .addBands(season.sin().rename('sin')) # 2. seasonal\n .addBands(season.cos().rename('cos')) # 3. seasonal\n .addBands(image.normalizedDifference().rename('NDVI')) # 4. response\n .toFloat()\n )\n\n\n# Define the axes of variation in the collection array.\nimage_axis = 0\nband_axis = 1\n\n# Convert the collection to an array.\narray = collection.map(make_variables).toArray()\n\n# Check the length of the image axis (number of images).\narray_length = array.arrayLength(image_axis)\n# Update the mask to ensure that the number of images is greater than or\n# equal to the number of predictors (the linear model is solvable).\narray = array.updateMask(array_length.gt(4))\n\n# Get slices of the array according to positions along the band axis.\npredictors = array.arraySlice(band_axis, 0, 4)\nresponse = array.arraySlice(band_axis, 4)\n```\n\nNote that `arraySlice()` returns all the images in the time series for the\nrange of indices specified along the `bandAxis` (the 1-axis). At this point,\nmatrix algebra can be used to solve for the OLS coefficients:\n\n### Code Editor (JavaScript)\n\n```javascript\n// Compute coefficients the hard way.\nvar coefficients1 = predictors.arrayTranspose().matrixMultiply(predictors)\n .matrixInverse().matrixMultiply(predictors.arrayTranspose())\n .matrixMultiply(response);\n```\nPython setup\n\nSee the [Python Environment](/earth-engine/guides/python_install) page for information on the Python API and using\n`geemap` for interactive development. \n\n```python\nimport ee\nimport geemap.core as geemap\n```\n\n### Colab (Python)\n\n```python\n# Compute coefficients the hard way.\ncoefficients_1 = (\n predictors.arrayTranspose()\n .matrixMultiply(predictors)\n .matrixInverse()\n .matrixMultiply(predictors.arrayTranspose())\n .matrixMultiply(response)\n)\n```\n\nAlthough this method works, it is inefficient and makes for difficult to read code. A\nbetter way is to use the `pseudoInverse()` method\n(`matrixPseudoInverse()` for an array image):\n\n### Code Editor (JavaScript)\n\n```javascript\n// Compute coefficients the easy way.\nvar coefficients2 = predictors.matrixPseudoInverse()\n .matrixMultiply(response);\n```\nPython setup\n\nSee the [Python Environment](/earth-engine/guides/python_install) page for information on the Python API and using\n`geemap` for interactive development. \n\n```python\nimport ee\nimport geemap.core as geemap\n```\n\n### Colab (Python)\n\n```python\n# Compute coefficients the easy way.\ncoefficients_2 = predictors.matrixPseudoInverse().matrixMultiply(response)\n```\n\nFrom a readability and computational efficiency perspective, the best way to get the OLS\ncoefficients is `solve()` (`matrixSolve()` for an array image). The\n`solve()` function determines how to best solve the system from characteristics\nof the inputs, using the pseudo-inverse for overdetermined systems, the inverse for square\nmatrices and special techniques for nearly singular matrices:\n\n### Code Editor (JavaScript)\n\n```javascript\n// Compute coefficients the easiest way.\nvar coefficients3 = predictors.matrixSolve(response);\n```\nPython setup\n\nSee the [Python Environment](/earth-engine/guides/python_install) page for information on the Python API and using\n`geemap` for interactive development. \n\n```python\nimport ee\nimport geemap.core as geemap\n```\n\n### Colab (Python)\n\n```python\n# Compute coefficients the easiest way.\ncoefficients_3 = predictors.matrixSolve(response)\n```\n\nTo get a multi-band image, project the array image into a lower dimensional space, then\nflatten it:\n\n### Code Editor (JavaScript)\n\n```javascript\n// Turn the results into a multi-band image.\nvar coefficientsImage = coefficients3\n // Get rid of the extra dimensions.\n .arrayProject([0])\n .arrayFlatten([\n ['constant', 'trend', 'sin', 'cos']\n]);\n```\nPython setup\n\nSee the [Python Environment](/earth-engine/guides/python_install) page for information on the Python API and using\n`geemap` for interactive development. \n\n```python\nimport ee\nimport geemap.core as geemap\n```\n\n### Colab (Python)\n\n```python\n# Turn the results into a multi-band image.\ncoefficients_image = (\n coefficients_3\n # Get rid of the extra dimensions.\n .arrayProject([0]).arrayFlatten([['constant', 'trend', 'sin', 'cos']])\n)\n```\n\nExamine the outputs of the three methods and observe that the resultant matrix of\ncoefficients is the same regardless of the solver. That `solve()` is flexible\nand efficient makes it a good choice for general purpose linear modeling."]]