Question

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]])
Était-ce utile?

La solution

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

Autres conseils

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.

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.]]
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top