Как использовать окно поиска в numpy и сохранить максимальное значение и все остальные значения в ноль - PullRequest
0 голосов
/ 03 мая 2018

У меня есть двумерный массив, например (101 строка и 100 столбцов). Теперь я хочу создать окно поиска или блок из (3 строки x 3 столбца), которые будут перемещаться по массиву и определять самое высокое значение, выбирать его и сохранять все другие значения в виде нулей, используя python и numpy. Например

x = ([[1,2,3,4,5,6,7,8,9,10],
     [2,5,4,5,3,4,6,7,5,3],
     [3,3,4,5,6,7,3,4,5,8]]

Использование функции поиска 2x2 x.some, например, начиная с верхнего левого угла, даст результат

Result = ([0,0...
          [0,5... for the 1st iteration so the the whole result should look like this 


Result = ([[0,0,0,0,0,6,0,8,0,10],
           [0,5,0,5,0,0,0,0,0,0],
           [3,3,0,5,0,7,0,4,0,8]]

Обратите внимание, что последняя строка окна поиска должна была измениться с массива 2x2 на 2x1, потому что окно поиска не перекрывается

Ваша помощь будет принята с благодарностью. Заранее спасибо

1 Ответ

0 голосов
/ 03 мая 2018

Вот подход, использующий skimage.util.view_as_blocks:

>>> import numpy as np
>>> import skimage.util as su
>>> 
>>> def split_axis(N, n):
...     q, r = divmod(N, n)
...     left = ((np.s_[:q*n], n),) if q else ()
...     right = ((np.s_[q*n:], r),) if r else ()
...     return (*left, *right)
... 
>>> def block_max(x, block, inplace=False):
...     if not inplace:
...         x = x.copy()
...     xi, xj = x.shape
...     bi, bj = block
...     for ci, ri in split_axis(xi, bi):
...         for cj, rj in split_axis(xj, bj):
...             vab = su.view_as_blocks(x[ci, cj], (ri, rj))
...             vab[vab < vab.max(axis=(-1, -2), keepdims=True)] = 0
...     return x
... 
>>> x = ([[1,2,3,4,5,6,7,8,9,10],
...      [2,5,4,5,3,4,6,7,5,3],
...      [3,3,4,5,6,7,3,4,5,8]])
>>> 
>>> x = np.array(x)
>>> 
>>> block_max(x, (2, 2))
array([[ 0,  0,  0,  0,  0,  6,  0,  8,  0, 10],
       [ 0,  5,  0,  5,  0,  0,  0,  0,  0,  0],
       [ 3,  3,  0,  5,  0,  7,  0,  4,  0,  8]])

Если у вас нет skimage:

>>> def view_as_blocks(x, blockshape):
...     *xs, xi, xj = x.shape
...     bi, bj = blockshape
...     return np.ascontiguousarray(x).reshape(*xs, xi//bi, xj//bj, *blockshape)

Ваш обновленный вопрос (без проверки):

>>> def block_max(x, block):
...     out = np.zeros_like(x)
...     xi, xj = x.shape
...     bi, bj = block
...     for ci, ri in split_axis(xi, bi):
...         for cj, rj in split_axis(xj, bj):
...             vab = su.view_as_blocks(x[ci, cj], (ri, rj))
...             oab = su.view_as_blocks(out[ci, cj], (ri, rj))
...             vmx = vab.max(axis=(-1, -2), keepdims=True)
...             vmn = vab.min(axis=(-1, -2), keepdims=True)
...             cond = vmx - vmn > 2
...             oab[cond & (vab == vmx)] == 1
...             oab[cond & (vab == vmn)] == 2
...     return out
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...