Regrid numpy array based on cell area
<pre><code>import numpy as np
from skimage.measure import block_reduce

arr = np.random.random((6, 6))
area_cell = np.random.random((6, 6))

block_reduce(arr, block_size=(2, 2), func=np.ma.mean)
</code></pre>

<p>I would like to regrid a numpy array <code>arr</code> from 6 x 6 size to 3 x 3. Using the skimage function block_reduce for this.</p>

<p>However, <code>block_reduce</code> assumes each grid cell has same size. How can I solve this problem, when each grid cell has a different size? In this case size of each grid cell is given by the numpy array <code>area_cell</code></p>

<p>-- EDIT:</p>

<p>An example:</p>

<p><code>arr</code></p>

<pre><code>0.25    0.58    0.69    0.74
0.49    0.11    0.10    0.41
0.43    0.76    0.65    0.79
0.72    0.97    0.92    0.09
</code></pre>

<p>If all elements of <code>area_cell</code> were 1, and we were to convert 4 x 4 arr into 2 x 2, result would be:</p>

<pre><code>0.36    0.48
0.72    0.61
</code></pre>

<p>However, if <code>area_cell</code> is as follows:</p>

<pre><code>0.00    1.00    1.00    0.00
0.00    1.00    0.00    0.50
0.20    1.00    0.80    0.80
0.00    0.00    1.00    1.00
</code></pre>

<p>Then, result becomes:</p>

<pre><code>0.17    0.22
0.21    0.54
</code></pre>

<p>It seems you are still reducing by blocks, but after scaling <code>arr</code> with <code>area_cell</code>. So, you just need to perform element-wise multiplication between these two arrays and use the same <code>block_reduce</code> code on that product array, like so -</p>

<pre><code>block_reduce(arr*area_cell, block_size=(2, 2), func=np.ma.mean)
</code></pre>

<p>Alternatively, we can simply use <a href="http://docs.scipy.org/doc/numpy/reference/generated/numpy.mean.html" rel="nofollow"><code>np.mean</code></a> after reshaping to a <code>4D</code> version of the product array, like so -</p>

<pre><code>m,n = arr.shape
out = (arr*area_cell).reshape(m//2,2,n//2,2).mean(axis=(1,3))
</code></pre>

<p>Sample run -</p>

<pre><code>In [21]: arr
Out[21]: 
array([[ 0.25,  0.58,  0.69,  0.74],
       [ 0.49,  0.11,  0.1 ,  0.41],
       [ 0.43,  0.76,  0.65,  0.79],
       [ 0.72,  0.97,  0.92,  0.09]])

In [22]: area_cell
Out[22]: 
array([[ 0. ,  1. ,  1. ,  0. ],
       [ 0. ,  1. ,  0. ,  0.5],
       [ 0.2,  1. ,  0.8,  0.8],
       [ 0. ,  0. ,  1. ,  1. ]])

In [23]: block_reduce(arr*area_cell, block_size=(2, 2), func=np.ma.mean)
Out[23]: 
array([[ 0.1725 ,  0.22375],
       [ 0.2115 ,  0.5405 ]])

In [24]: m,n = arr.shape

In [25]: (arr*area_cell).reshape(m//2,2,n//2,2).mean(axis=(1,3))
Out[25]: 
array([[ 0.1725 ,  0.22375],
       [ 0.2115 ,  0.5405 ]])
</code></pre>

python numpy skimage