Question:

I have a 2D array that I would like to down sample to compare it to another.

Lets say my array `x`

is `512x512`

, I'd like an array `y`

`128x128`

where the elements of `y`

are build using an interpolation of the values overs `4x4`

blocks of `x`

(this interpolation could just be taking the average, but other methodes, like geometric average, could be interesting)

So far I looked at `scipy.ndimage.interpolation.zoom`

but I don't get the results I want

```
>> x = np.arange(16).reshape(4,4)
>> print(x)
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
>> y = scipy.ndimage.interpolation.zoom(x, 0.5)
>> print(y)
[[ 0 3]
[12 15]]
```

I expected `y`

to be

```
[[ 2.5 4.5]
[10.5 12.5]]
```

Note that simply setting `dtype=np.float32`

doesn't solve that ...

What you seem to be looking for is the mean over blocks of 4, which is not obtainable with `zoom`

, since `zoom`

uses interpolation (see its docstring)

To obtain what you show, try the following

```
import numpy as np
x = np.arange(16).reshape(4, 4)
xx = x.reshape(len(x) // 2, 2, x.shape[1] // 2, 2).transpose(0, 2, 1, 3).reshape(len(x) // 2, x.shape[1] // 2, -1).mean(-1)
print xx
```

This yields

```
[[ 2.5 4.5]
[ 10.5 12.5]]
```

Alternatively, this can be done using `sklearn.feature_extraction.image.extract_patches`

```
from sklearn.feature_extraction.image import extract_patches
patches = extract_patches(x, patch_shape=(2, 2), extraction_step=(2, 2))
xx = patches.mean(-1).mean(-1)
print xx
```

However, if your goal is to subsample an image in a graceful way, then taking the mean over blocks of the image is <em>not</em> the right way to do it: It is likely to cause aliasing effects. What you should do in this case is smooth the image ever so slightly using `scipy.ndimage.gaussian_filter`

(e.g. `sigma=0.35 * subsample_factor`

) and then subsample simply by indexing `[::2, ::2]`

`sklearn.feature_extraction.image.extract_patches`

cleverly uses `np.lib.stride_tricks.as_strided`

to produce a <em>windowed</em> array that can be operated on.

The `sliding_window`

function, found here
<a href="http://www.johnvinyard.com/blog/?p=268" rel="nofollow">Efficient Overlapping Windows with Numpy</a>, produces a windowed array with or without overlap
also and let's you get a glimpse of what is happening under the hood.

```
>>> a = np.arange(16).reshape(4,4)
```

`step_height,step_width`

determines the overlap for the windows - in your case the steps are the same as the window size, no overlap.

```
>>> window_height, window_width, step_height, step_width = 2, 2, 2, 2
>>> y = sliding_window(a, (window_height, window_width), (step_height,step_width))
>>> y
array([[[ 0, 1],
[ 4, 5]],
[[ 2, 3],
[ 6, 7]],
[[ 8, 9],
[12, 13]],
[[10, 11],
[14, 15]]])
```

Operate on the windows:

```
>>> y = y.mean(axis = (1,2))
>>> y
array([ 2.5, 4.5, 10.5, 12.5])
```

You need to determine the final shape depending on the number of windows.

```
>>> final_shape = (2,2)
>>> y = y.reshape(final_shape)
>>> y
array([[ 2.5, 4.5],
[ 10.5, 12.5]])
```

Searching SO for `numpy`

, window, array should produce numerous other answers and possible solutions.