4
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)

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

However, block_reduce 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 area_cell

-- EDIT:

An example:

arr

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

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

0.36    0.48
0.72    0.61

However, if area_cell is as follows:

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

Then, result becomes:

0.17    0.22
0.21    0.54
4
  • I don't understand what you mean. Do you mean to say that block_size must all have the same scaling factors? They can be arbitrary positive integers. Commented Sep 1, 2016 at 16:46
  • @rayryeng, I want to do weighted average rather than simple mean. The weights are defined in area_cell. The block_size is not relevant in this case. In my particular use case, block_size always has same scaling factors. Commented Sep 1, 2016 at 18:05
  • 1
    Use some numeric values as input elements and show us the expected o/p? Commented Sep 1, 2016 at 20:08
  • @Divakar, added an example to the question. Commented Sep 1, 2016 at 22:48

1 Answer 1

2

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

block_reduce(arr*area_cell, block_size=(2, 2), func=np.ma.mean)

Alternatively, we can simply use np.mean after reshaping to a 4D version of the product array, like so -

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

Sample run -

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 ]])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.