получить среднее значение numy элементов из 2D массива, используя маску - PullRequest
0 голосов
/ 26 ноября 2018

Я хочу получить среднее значение numy элементов в 2d массиве вокруг выбранной точки с выбранным размером и формой окрестности.

Я сделал пример, чтобы объяснить, что я пытаюсь сделать.Это не работает с большинством входных данных еще из-за проблем формы.Прежде чем я продолжу, есть ли элегантный или встроенный способ сделать это?

import numpy as np
from skimage.morphology import disk

def get_sub_array_about_point(array, point, size):
    i1 = point[0]-(size-1)
    i2 = point[0]+size
    j1 = point[1]-(size-1)
    j2 = point[1]+size
    return array[i1:i2, j1:j2]

def get_neighborhood_mean(array, point, size, shape):

    sub_array = get_sub_array_about_point(test_array, point, size)
    """
    array([[10.1,  1.2,  1.3],
           [ 2.1, 20.2,  2.3],
           [ 3.1,  3.2,  3.3]])
    """

    masked_sub_array = np.ma.masked_where(mask==False, sub_array)
    masked_sub_array
    """
    masked_array(
      data=[[--, 1.2, --],
            [2.1, 20.2, 2.3],
            [--, 3.2, --]],
      mask=[[ True, False,  True],
            [False, False, False],
            [ True, False,  True]],
      fill_value=1e+20)
    """

    return masked_sub_array.mean()
    """
    5.8
    """

test_array = np.array([[0. , 0.1 , 0.2 , 0.3 ],
                       [1. , 10.1 , 1.2, 1.3 ],
                       [2. , 2.1, 20.2, 2.3 ],
                       [3. , 3.1 , 3.2, 3.3 ]])

mask = disk(1)
"""
array([[0, 1, 0],
       [1, 1, 1],
       [0, 1, 0]], dtype=uint8)
"""
get_neighborhood_mean(test_array, point=(2,2), size=2, shape=mask)

1 Ответ

0 голосов
/ 26 ноября 2018

Элегантный способ сделать это с помощью 2D свертки .Если вы нормализуете элементы в маске (путем деления на сумму элементов), свертка даст вам двумерный массив, который является средним по окрестности.

from scipy.signal import convolve2d

test_array = np.array([[0. , 0.1 , 0.2 , 0.3 ],
                       [1. , 10.1 , 1.2, 1.3 ],
                       [2. , 2.1, 20.2, 2.3 ],
                       [3. , 3.1 , 3.2, 3.3 ]])

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

# Normalize mask
mask = mask / float(np.sum(mask))

convolve2d(test_array, mask, mode='valid')
# array([[2.9, 6.6],
#        [7.5, 5.8]])

Используя mode='valid', среднее значениезначения даны только для элементов, которые не требуют заполнения, где маска может помещаться без необходимости выходить за край массива.Таким образом, в вышеприведенном случае выходной массив предназначен только для центральных 4 элементов test_array.

Если вы хотите получить средние значения окрестностей для всех элементов, в том числе по краям, заполнение нулями можетиспользовать настройку mode='same'.

convolve2d(test_array, mask, mode='same')
# array([[0.22, 2.08, 0.36, 0.36],
#        [2.62, 2.9 , 6.6 , 1.02],
#        [1.62, 7.5 , 5.8 , 5.42],
#        [1.62, 2.28, 5.96, 1.76]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...