Извлечение блоков из матрицы вокруг позиции индекса - PullRequest
0 голосов
/ 28 февраля 2020

Как (в python3) можно извлечь несколько блоков размером n на m из массива M-N, центрированных в каждом элементе?

, например, в матрице 9 на 9 и, используя блок 3 на 3, мне нужно извлечь блок в каждой позиции матрицы. Сложность здесь (для меня) заключается в том, что элемент I, J внутри его соответствующего блока меняет положение.

здесь изображение, на котором я показываю 9 блоков (для 9 позиций) из 9 на 1 9 матрица (конечно, есть 81 блок для извлечения)

Here an image

Приведенный ниже код отлично работает ( ТОЛЬКО ) для углов , Здесь размер блока (Wsize-by-Wsize) является нечетным числом, чтобы найти индекс (Eindex [0], Eindex 1 ) в середине.

def windowing(array,Wsize,Eindex):
    '''
    Extract an sub-array of array for the element located in the index 'Eindex'.
    Wsize-by-Wsize is the shape of the window 
    '''
    block=np.zeros(tuple(Wsize))
    k0 = int((Wsize[0]-1)/2)
    k1 = int((Wsize[1]-1)/2) 
    s0 =  Wsize[0]
    s1 =  Wsize[1]
    I =  array.shape[0]-1 # las index in i-direction
    J =  array.shape[1]-1 # las index in i-direction
    if (Eindex[0]==0) and (Eindex[1]==0):
        block=array[0:Eindex[0]+s0,0:Eindex[1]+s1]
        return block
    elif (Eindex[0]==I) and (Eindex[1]==0):
        block=array[-s0:,0:Eindex[1]+s1]
        return block
    elif (Eindex[0]==0) and (Eindex[1]==J):
        block=array[0:Eindex[0]+s0,-s1:]
        return block
    elif (Eindex[0]==I) and (Eindex[1]==J):
        block=array[-s0:,-s1:]
        return block

например, проверка:

x = np.arange(81).reshape(9,9)
print(windowing(x,[3,3],[0,0]))
print(windowing(x,[3,3],[8,8))
print(windowing(x,[3,3],[8,0]))
print(windowing(x,[3,3],[0,8]))

Ответы [ 2 ]

1 голос
/ 29 февраля 2020

Вот подход, который использует произвольные массивы, координаты и размеры окон.

def compute_indices(c, ws, length):

    # default setting: % operations to accommodate odd/even window sizes
    low, high = c - (ws//2), c + (ws//2) + ws%2 

    # correction for overlap with borders of array
    if low<0:
        low, high = 0, ws
    elif high>length:
        low, high = -ws, None

    return low, high


def extract_block(arr, coords, window_size=(3,3)):

    # extract array shapes and window sizes into single 
    # variables
    len_r, len_c = arr.shape
    wsr, wsc = window_size

    # extract coords and correct for 0-indexing
    r, c = coords
    r0, c0 = r-1, c-1

    row_low, row_high = compute_indices(r0, wsr, len_r)
    col_low, col_high = compute_indices(c0, wsc, len_c)

    return arr[row_low:row_high, col_low:col_high]

тестовые случаи:

a = np.arange(81).reshape(9,9)

extract_block(a, [1,1], (3,3))
array[[ 0  1  2]
     [ 9 10 11]
     [18 19 20]]

extract_block(a, [9,9], (3,3))
array([[60, 61, 62],
       [69, 70, 71],
       [78, 79, 80]])

extract_block(a, [5,2], (3,6))
array([[27, 28, 29, 30, 31, 32],
       [36, 37, 38, 39, 40, 41],
       [45, 46, 47, 48, 49, 50]])
1 голос
/ 28 февраля 2020

Вы можете использовать numpy следующим образом:

import numpy as np
# Array 9 by 9
x = np.arange(81).reshape((9, 9))
# -1 is important for the indexing
desired_position = np.array([[1,1], [1,5], [1,9], [5,1], [5,5], [5,9], [9,1], [9,5], [9,9]]) - 1
#print(desired_position)
for dp in desired_position:
    pos = []
    p1, p2 =dp[0] - 1, dp[0] + 2
    if p1 <= 0:
        p1, p2 = 0, 3
    elif p2 >= x.shape[0]:
        p2, p1 = x.shape[0], x.shape[0] - 3
    pos.append([p1, p2])

    p1, p2 = dp[1] - 1, dp[1] + 2
    if p1 <= 0:
        p1, p2 = 0, 3
    elif p2 >= x.shape[1]:
        p2, p1 = x.shape[1], x.shape[1] - 3
    pos.append([p1, p2])
    print(x[pos[0][0]:pos[0][1],pos[1][0]:pos[1][1]])

Пожалуйста, прочитайте документы для numpy для получения дополнительной информации

Я отредактировал код, поэтому теперь это работает.

...