How to downsample a matrix by averaging elements n*n with numpy in python ?


Examples of how to do downsample a matrix by averaging elements n*n with numpy in python:

Create a matrix

Let's first create a simple matrix:

Note: see the previous note how to upsample an array by repeating elements using numpy in python

import numpy as np

a = np.array([[0,1], [2,3]])
a = np.kron(a, np.ones((3,3)))

print(a)


[[0. 0. 0. 1. 1. 1.]
 [0. 0. 0. 1. 1. 1.]
 [0. 0. 0. 1. 1. 1.]
 [2. 2. 2. 3. 3. 3.]
 [2. 2. 2. 3. 3. 3.]
 [2. 2. 2. 3. 3. 3.]]

print(a.shape)

returns

(6, 6)

Downsampling the matrix a by avergaging 2*2 elements

Example of how to downsample by avergaging 2 by 2 elements of matrix a:

n = 2
b = a.shape[0]//n

a_downsampled = a.reshape(-1, n, b, n).sum((-1, -3)) / n

print(a_downsampled)

returns

[[0. 1. 2.]
 [2. 3. 4.]
 [4. 5. 6.]]

Using a 2d convolution

Another example using scipy.signal.convolve2d

from scipy.signal import convolve2d

kernel = np.ones((n, n))
convolved = convolve2d(a, kernel, mode='valid')
a_downsampled = convolved[::n, ::n] / n

print(a_downsampled)

returns:

[[0. 1. 2.]
 [2. 3. 4.]
 [4. 5. 6.]]

References