# Arrays and Array Images

Arrays in Earth Engine are constructed from lists of numbers and lists of lists. The degree of nesting determines the number of dimensions. To get started with a simple, motivated example, consider the following example of an `Array` created from Landsat 5 tasseled cap (TC) coefficients (Crist and Cicone 1984):

```// Create an Array of Tasseled Cap coefficients.
var coefficients = ee.Array([
[0.3037, 0.2793, 0.4743, 0.5585, 0.5082, 0.1863],
[-0.2848, -0.2435, -0.5436, 0.7243, 0.0840, -0.1800],
[0.1509, 0.1973, 0.3279, 0.3406, -0.7112, -0.4572],
[-0.8242, 0.0849, 0.4392, -0.0580, 0.2012, -0.2768],
[-0.3280, 0.0549, 0.1075, 0.1855, -0.4357, 0.8085],
[0.1084, -0.9022, 0.4120, 0.0573, -0.0251, 0.0238]
]);
```

Confirm that this is a 6x6, 2-D Array using `length()`, which will return the lengths of each axis:

```// Print the dimensions.
print(coefficients.length()); //    [6,6]
```

The following table illustrates the arrangement of the matrix entries along the 0-axis and the 1-axis:

1-axis ->
012345
00.30370.27930.47430.55850.50820.1863
1-0.2848-0.2435-0.54360.72430.0840-0.1800
0-axis20.15090.19730.32790.3406-0.7112-0.4572
3-0.82420.08490.4392-0.05800.2012-0.2768
4-0.32800.05490.10750.1855-0.43570.8085
50.1084-0.90220.41200.0573-0.02510.0238

The indices on the left of the table indicate positions along the 0-axis. The n-th element within each list on the 0-axis is in the n-th position along the 1-axis. For example, the entry at coordinate [3,1] of the array is 0.0849. Suppose ‘greenness’ is the TC component of interest. You can get the greenness sub-matrix using `slice()`:

```// Get the 1x6 greenness slice, display it.
var greenness = coefficients.slice({axis: 0, start: 1, end: 2, step: 1});
print(greenness);
```

The 2-D greenness matrix should look something like:

```[[-0.2848,-0.2435,-0.5436,0.7243,0.0840,-0.1800]]
```

Observe that the `start` and `end` parameters of `slice()` correspond to the 0-axis indices displayed in the table (`start` is inclusive and `end` is exclusive).

## Array Images

To get a greenness image, matrix multiply the bands of a Landsat 5 image by the greenness matrix. To do that, first convert the multi-band Landsat image into an “Array Image”, where each pixel is an `Array` of band values. For example:

```// Load a Landsat 5 image, select the bands of interest.
var image = ee.Image('LANDSAT/LT05/C01/T1_TOA/LT05_044034_20081011')
.select(['B1', 'B2', 'B3', 'B4', 'B5', 'B7']);

// Make an Array Image, with a 1-D Array per pixel.
var arrayImage1D = image.toArray();

// Make an Array Image with a 2-D Array per pixel, 6x1.
var arrayImage2D = arrayImage1D.toArray(1);
```

In this example, note that `toArray()` converts `image` to an array image in which each pixel is a 1-D vector, the entries of which correspond to the 6 values at the corresponding positions in the bands of `image`. An array image of 1-D vectors created in this manner has no concept of 2-D shape. To perform 2-D only operations such as matrix multiplication, convert it into a 2-D array per-pixel image with `toArrray(1)`. In each pixel of the 2-D array image, there is a 6x1 matrix of band values. To see this, consider the following toy example:

```var array1D = ee.Array([1, 2, 3]);              // [1,2,3]
var array2D = ee.Array.cat([array1D], 1);     // [,,]
```

Observe that the `array1D` vector varies along the 0-axis. The `array2D` matrix does as well, but it’s got an extra dimension. Calling `toArray(1)` on the array image is like calling `cat(bandVector, 1)` on every pixel. Using the 2-D array image, left multiply by an image where each pixel contains a 2-D matrix of greenness coefficients:

```// Do a matrix multiplication: 1x6 times 6x1.
// Cast the greenness Array to an Image prior to multiplication.
var greennessArrayImage = ee.Image(greenness).matrixMultiply(arrayImage2D);
```

The result is a new array image where every pixel is the 1x1 matrix that results from matrix multiplying the 1x6 greenness matrix (left) and the 6x1 band matrix (right). For display purposes, convert to a regular, one-band image with `arrayGet()`:

```// Get the result from the 1x1 array in each pixel of the 2-D array image.
var greennessImage = greennessArrayImage.arrayGet([0, 0]);

// Display the input imagery with the greenness result.
Map.setCenter(-122.3, 37.562, 10);
Map.addLayer(image, {bands: ['B4', 'B3', 'B2'], min: 0, max: 0.5}, 'image');
Map.addLayer(greennessImage, {min: -0.1, max: 0.1}, 'greenness');
```

Here is a complete example, which uses the entire coefficients array to compute multiple tasseled cap components at once and display the result:

```// Define an Array of Tasseled Cap coefficients.
var coefficients = ee.Array([
[0.3037, 0.2793, 0.4743, 0.5585, 0.5082, 0.1863],
[-0.2848, -0.2435, -0.5436, 0.7243, 0.0840, -0.1800],
[0.1509, 0.1973, 0.3279, 0.3406, -0.7112, -0.4572],
[-0.8242, 0.0849, 0.4392, -0.0580, 0.2012, -0.2768],
[-0.3280, 0.0549, 0.1075, 0.1855, -0.4357, 0.8085],
[0.1084, -0.9022, 0.4120, 0.0573, -0.0251, 0.0238]
]);

// Load a Landsat 5 image, select the bands of interest.
var image = ee.Image('LANDSAT/LT05/C01/T1_TOA/LT05_044034_20081011')
.select(['B1', 'B2', 'B3', 'B4', 'B5', 'B7']);

// Make an Array Image, with a 1-D Array per pixel.
var arrayImage1D = image.toArray();

// Make an Array Image with a 2-D Array per pixel, 6x1.
var arrayImage2D = arrayImage1D.toArray(1);

// Do a matrix multiplication: 6x6 times 6x1.
var componentsImage = ee.Image(coefficients)
.matrixMultiply(arrayImage2D)
// Get rid of the extra dimensions.
.arrayProject()
.arrayFlatten(
[['brightness', 'greenness', 'wetness', 'fourth', 'fifth', 'sixth']]);

// Display the first three bands of the result and the input imagery.
var vizParams = {
bands: ['brightness', 'greenness', 'wetness'],
min: -0.1, max: [0.5, 0.1, 0.1]
};
Map.setCenter(-122.3, 37.562, 10);
Map.addLayer(image, {bands: ['B4', 'B3', 'B2'], min: 0, max: 0.5}, 'image');
Note that when getting bands from an array image, first get rid of the extra dimensions with `project()`, then convert it back to a regular image with `arrayFlatten()`. The output should look something like: