Simplify the matrix by averaging multiple cells

I have a large 2D matrix that needs to be reduced (for example: convert from 100x100 to 10x10).

My goal is mainly: to split the nxn matrix into smaller mxm matrices, average the cells in these mxm slices, and then build a new (smaller) matrix from these mxm fragments.

I am going to use something like matrix[a::b, c::d]to extract smaller matrices and then average these values, but this seems too complicated. Is there a better way to do this?

+4
source share
3 answers

You can split your array into blocks using a function view_as_blocks(in a scikit image).

2D- 4D , :

>>> import skimage.util as ski
>>> import numpy as np
>>> a = np.arange(16).reshape(4,4) # 4x4 array
>>> ski.view_as_blocks(a, (2,2))
array([[[[ 0,  1],
         [ 4,  5]],

        [[ 2,  3],
         [ 6,  7]]],


       [[[ 8,  9],
         [12, 13]],

        [[10, 11],
         [14, 15]]]])

:

>>> ski.view_as_blocks(a, (2,2)).mean(axis=(2,3))
array([[  2.5,   4.5],
       [ 10.5,  12.5]])

: view_as_blocks , ( ). NumPy as_strided, , scikit-, .

+5

ski-learn .

M=np.arange(10000).reshape(100,100)
M1=M.reshape(10,10,10,10)
M2=M1.mean(axis=(1,3))

, ,

In [127]: M2[0,0]
Out[127]: 454.5

In [128]: M[:10,:10].mean()
Out[128]: 454.5

In [131]: M[-10:,-10:].mean()
Out[131]: 9544.5

In [132]: M2[-1,-1]
Out[132]: 9544.5

.transpose([0,2,1,3]) 2 , view_as_blocks.

(100,100), reshape 2 , as_strided, .

, .

as_strided(M,shape=(10,10,10,10),strides=(8000,80,800,8)).mean((2,3))
as_strided(M,shape=(10,10,10,10),strides=(8000,800,80,8)).mean((1,3))
+1

, scipy.ndimage.zoom() . ( ) 0 5. , 0 .

from scipy import ndimage as ndi
import numpy as np

M=np.arange(1000000).reshape(1000,1000)

shrinkby=10

Mfilt = ndi.filters.uniform_filter(input=M, size=shrinkby)
Msmall = ndi.interpolation.zoom(input=Mfilt, zoom=1./shrinkby, order=0)

, . , , , order=0 .

10% , ..

print M.shape, Msmall.shape

(1000, 1000) (100, 100) ,

%timeit Mfilt = ndi.filters.uniform_filter(input=M, size=shrinkby)
%timeit Msmall = ndi.interpolation.zoom(input=Mfilt, zoom=1./shrinkby, order=0)

10 loops, best of 3: 20.5 ms per loop uniform_filter 1000 loops, best of 3: 1.67 ms per loop zoom.

0
source

All Articles