When using multidimensional arrays, it is very important to understand the order of the indices, and how they are interpreted by different modules.

The indices of 2-D arrays are ordered in the same way as matrix indices are. Example:

In [1]:

```
import numpy as np
m = np.array([[1,2,3],[4,5,6]])
m
```

Out[1]:

In [2]:

```
m[1,0]
```

Out[2]:

The first index (here set to 1) counts rows (i.e. it counts from top to bottom). The second index (here set to 0) counts columns (i.e. it counts from left to right). This is exactly the way it is done with matrices.

Note that we can regard the above matrix as a set of rows:

In [4]:

```
m[1]
```

Out[4]:

We can thus also get element `[1,0]`

by first extracting the row, then extracting the column:

In [5]:

```
m[1][0]
```

Out[5]:

In [6]:

```
row=m[1]
row[0]
```

Out[6]:

But when we want to slice, there can be confusing things happening:

In [7]:

```
m[:,0]
```

Out[7]:

In [8]:

```
m[:][0]
```

Out[8]:

Any idea why these two ways of slicing give different results?

The above `m[1][0]`

interpretation of a 2D array also is related to the concept of "inner index" and "outer index". What does that mean? The point is that a 2D array is, in computer memory, in fact a 1D array. It is merely *interpreted* as a 2D array. The way to see this is like this:

In [36]:

```
mflat = m.flatten()
mflat
```

Out[36]:

The 'flattened' array is the *actual* array as it is in memory. You see that the rows are concatenated after each other. You can addess the element `m[ivert,ihori]`

also directly in `mflat`

:

In [39]:

```
ivert, ihori = 1,0
print(m[ivert,ihori])
print(mflat[ivert*3+ihori])
```

Given that `mflat`

is the *actual* array (below the surface, so to speak), the 2-D array is just a *shape* given to that array. With `reshape()`

we can change the shape of this dataset:

In [43]:

```
malt = m.reshape(3,2)
malt
```

Out[43]:

Note that this is different from the transpose:

In [44]:

```
m.T
```

Out[44]:

Another confusing thing can be when we make 2D arrays as maps in an x-y plane. Let's make such a map and see what happens:

In [32]:

```
x=np.linspace(-1,1,40)
y=np.linspace(-0.5,0.5,20)
xx,yy=np.meshgrid(x,y)
ff=np.cos(xx*7.5)*np.exp(-0.5*((yy-0.25)/0.15)**2)
```

In [33]:

```
%matplotlib inline
import matplotlib.pyplot as plt
plt.imshow(ff)
```

Out[33]:

First note, that the y-axis goes from top to bottom (just like with a matrix). This is also how the old-fashioned TV set worked: an electron beam went from left to right (rows), and then from top to bottom. It is also the way we read a book. But it is not how mathematians make a figure: we tend to put the y-axis from bottom to top. You can set this with `origin='lower'`

:

In [34]:

```
plt.imshow(ff,origin='lower')
```

Out[34]:

Now let's have a closer look at the index order:

In [35]:

```
ff.shape
```

Out[35]:

As you can see by the outcome of `ff.shape`

: The x-index (which has 40 elements) is right, the y-index (which has 20 elements) is left. So the index-order is `ff[index_y,index_x]`

, i.e. (y,x). This can be confusing, because in mathematics we are used to set the order to (x,y). But from the python perspective this makes sense: x is the "inner index" and y is the "outer index".

So the *index ordering* is y,x, but the *order of the arguments* for `np.meshgrid()`

are x,y (opposite).

You can, **if you like**, force meshgrid to set the index order also to x,y:

In [47]:

```
xx,yy=np.meshgrid(x,y,indexing='ij')
ff=np.cos(xx*7.5)*np.exp(-0.5*((yy-0.25)/0.15)**2)
```

In [48]:

```
ff.shape
```

Out[48]:

But then you have to be careful when using `imshow()`

: You now have to use the transpose:

In [51]:

```
plt.imshow(ff.T,origin='lower')
```

Out[51]:

In [52]:

```
x=np.linspace(-1,1,40)
y=np.linspace(-0.5,0.5,20)
z=np.linspace(0,3,10)
xx,yy,zz=np.meshgrid(x,y,z)
ff=np.cos(xx*7.5)*np.exp(-0.5*((yy-0.25)/0.15)**2)*np.exp(-zz)
```

In [53]:

```
ff.shape
```

Out[53]:

Now things get *really* confusing! As you see, the index order is now: y,x,z, while the argument order to `meshgrid()`

remains x,y,z.

Therefore, for 3-D and higher-dimensional arrays, I recommend always to use `indexing='ij'`

!

In [ ]:

```
```