1

How can I downscale the raster data of 4*6 size into 2*3 size using 'mode' i.e., most common value with in 2*2 pixels?

import numpy as np
data=np.array([
[0,0,1,1,1,1],
[1,0,0,1,1,1],
[1,0,1,1,0,1],
[1,1,0,1,0,0]])

The result should be:

result = np.array([
    [0,1,1],
    [1,1,0]])
4
  • I was expecting result to be full of 1s, because in any 2x2 block there is always a 1. Commented May 5, 2014 at 12:19
  • Since the maximum occurred element among '0,0,1,0' in the first 2*2 block is 0, I want to get 0 as the output. Commented May 5, 2014 at 12:22
  • I have asked different question for desired result as you have mentioned Commented May 5, 2014 at 12:24
  • @neha - I have changed "maximum occurred" to "most common" which I think is easier to understand. I hope you don't mind. Commented May 5, 2014 at 15:41

3 Answers 3

1

Please refer to this thread for a full explanation. The following code will calculate your desired result.

from sklearn.feature_extraction.image import extract_patches

data=np.array([
    [0,0,1,1,1,1],
    [1,0,0,1,1,1],
    [1,0,1,1,0,1],
    [1,1,0,1,0,0]])

patches = extract_patches(data, patch_shape=(2, 2), extraction_step=(2, 2))
most_frequent_number = ((patches > 0).sum(axis=-1).sum(axis=-1) > 2).astype(int)
print most_frequent_number
Sign up to request clarification or add additional context in comments.

Comments

1

Here's one way to go,

from itertools import product
from numpy import empty,argmax,bincount
res = empty((data.shape[0]/2,data.shape[1]/2))
for j,k in product(xrange(res.shape[0]),xrange(res.shape[1])):
    subvec = data[2*j:2*j+2,2*k:2*k+2].flatten()
    res[j,k]=argmax(bincount(subvec))

This works as long as the input data contains an integer number of 2x2 blocks.

Notice that a block like [[0,0],[1,1]] will lead 0 as result, because argmax returns the index of the first occurrence only. Use res[j,k]=subvec.max()-argmax(bincount(subvec)[::-1]) if you want these 2x2 blocks to count as 1.

Comments

1

There appears to be more than one statistic you wish to collect about each block. Using toblocks (below) you can apply various computations to the last axis of blocks to obtain the desired statistics:

import numpy as np
import scipy.stats as stats

def toblocks(arr, nrows, ncols):
    h, w = arr.shape
    blocks = (arr.reshape(h // nrows, nrows, -1, ncols)
              .swapaxes(1, 2)
              .reshape(h // nrows, w // ncols, ncols * nrows))
    return blocks

data=np.array([
    [0,0,1,1,1,1],
    [1,0,0,1,1,1],
    [1,0,1,1,0,1],
    [1,1,0,1,0,0]])

blocks = toblocks(data, 2, 2)
vals, counts = stats.mode(blocks, axis=-1)
vals = vals.squeeze()
print(vals)
# [[ 0.  1.  1.]
#  [ 1.  1.  0.]]

Comments

Your Answer

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