使用最常见的值更改numpy数组的结构

时间:2014-05-05 12:14:49

标签: python numpy scipy

如何使用“模式”将4 * 6大小的栅格数据缩小为2 * 3大小,即最常见的值为2 * 2像素?

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

结果应为:

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

3 个答案:

答案 0 :(得分:1)

这是一种方法,

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

只要输入data包含整数个2x2块,就可以正常工作。

请注意,[[0,0],[1,1]]之类的结果会导致0结果,因为argmax仅返回第一次出现的索引。如果您希望这些2x2块计为res[j,k]=subvec.max()-argmax(bincount(subvec)[::-1]),请使用1

答案 1 :(得分:1)

有关完整说明,请参阅this thread。以下代码将计算您想要的结果。

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

答案 2 :(得分:1)

There appears要为每个区块收集多个统计信息。使用toblocks(下方),您可以将各种计算应用于blocks的最后一个轴,以获得所需的统计信息:

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.]]