公告:所有在
2025 年 4 月 15 日之前注册使用 Earth Engine 的非商业项目都必须
验证是否符合非商业性质的资格条件,才能继续使用 Earth Engine。
数组转换
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
Earth Engine 支持数组转换,例如转置、转置和伪转置。
例如,假设对一组图片的时间序列进行普通最小二乘 (OLS) 回归。在以下示例中,将包含预测器和响应波段的图片转换为数组图片,然后通过三种方式“求解”以获取最小二乘系数估计值。首先,组装图片数据并转换为数组:
Code Editor (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 API 以及如何使用 geemap
进行交互式开发,请参阅
Python 环境页面。
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 系数:
Code Editor (JavaScript)
// Compute coefficients the hard way.
var coefficients1 = predictors.arrayTranspose().matrixMultiply(predictors)
.matrixInverse().matrixMultiply(predictors.arrayTranspose())
.matrixMultiply(response);
Python 设置
如需了解 Python API 以及如何使用 geemap
进行交互式开发,请参阅
Python 环境页面。
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()
):
Code Editor (JavaScript)
// Compute coefficients the easy way.
var coefficients2 = predictors.matrixPseudoInverse()
.matrixMultiply(response);
Python 设置
如需了解 Python API 以及如何使用 geemap
进行交互式开发,请参阅
Python 环境页面。
import ee
import geemap.core as geemap
Colab (Python)
# Compute coefficients the easy way.
coefficients_2 = predictors.matrixPseudoInverse().matrixMultiply(response)
从可读性和计算效率的角度来看,获取 OLS 系数的最佳方法是 solve()
(对于数组图片,则为 matrixSolve()
)。solve()
函数会根据输入的特征确定如何最佳地求解系统,对于过秩系统,使用伪逆;对于方阵,使用逆;对于接近奇异的矩阵,使用特殊技术:
Code Editor (JavaScript)
// Compute coefficients the easiest way.
var coefficients3 = predictors.matrixSolve(response);
Python 设置
如需了解 Python API 以及如何使用 geemap
进行交互式开发,请参阅
Python 环境页面。
import ee
import geemap.core as geemap
Colab (Python)
# Compute coefficients the easiest way.
coefficients_3 = predictors.matrixSolve(response)
如需获取多波段图像,请将数组图像投影到更低维的空间,然后将其展平:
Code Editor (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 API 以及如何使用 geemap
进行交互式开发,请参阅
Python 环境页面。
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()
灵活且高效,因此非常适合通用线性建模。
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-25。
[null,null,["最后更新时间 (UTC):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."]]