# Slicing high dimensional arrays

When we learned about matrices it wasn’t hard to think of slicing 2D matrices along rows and columns. But what about slicing higher dimensional matrices? I always get confused when I go above 3-dimensions. Interestingly, for me, an easy way to imagine slicing such high dimensional matrices is by using trees and thinking of how the numbers are stored in a computer.

Consider a 2x2x2x2 matrix, something we can construct as follows:

```a=pylab.arange(16)
a -> array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])

b=a.reshape((2,2,2,2))
b ->
array([[[[ 0,  1],
[ 2,  3]],

[[ 4,  5],
[ 6,  7]]],

[[[ 8,  9],
[10, 11]],

[[12, 13],
[14, 15]]]])
```

Now imagine the matrix is stored in the computer as a simple sequence of numbers (this is kind of true). What makes these numbers behave as a matrix is the indexing scheme. The indexing scheme can be thought of as a kind of tree.

Each level of the tree depicts a dimension, with the root being the outermost dimension and the leaves the inner-most dimensions.

When we slice the array, say by doing

```b[0,:,:,:] ->
array([[[0, 1],
[2, 3]],

[[4, 5],
[6, 7]]])
```

We are actually breaking off a branch of the tree and looking at that.

The same with deeper slices, such as

```b[0,0,:,:] ->
array([[0, 1],
[2, 3]])
```

But what about a slice that starts at the leaves, rather than the roots of the tree?

```b[:,:,:,0] ->
array([[[ 0,  2],
[ 4,  6]],

[[ 8, 10],
[12, 14]]])
```

In such a case I think in terms of breaking off unused branches/leaves and then merging the stubs to form a new tree.