Home > Net >  how to mask 2d array by if there are at least 2 neighbors greater than one value?
how to mask 2d array by if there are at least 2 neighbors greater than one value?

Time:12-12

For a 2d numpy array, e.g.,

import numpy as np
a = np.random.rand(5, 4)
a

a looks like

array([[0.92576936, 0.41860519, 0.26446948, 0.31691141],
       [0.31797497, 0.2044637 , 0.20939504, 0.54034017],
       [0.85781227, 0.40367301, 0.40215265, 0.95902499],
       [0.15700837, 0.10680368, 0.61971475, 0.35586694],
       [0.25211967, 0.98171005, 0.60740472, 0.89452886]])

Apparently, each element has neighbors. For elements in the border, it has 3 or 5 neighbors. And for central elements, it has 8. Thus, is there an efficient and elegant way to mask a by only selecting elements and their neighbors together greater than 0.5? That means, do not consider isolated elements larger than 0.5, whose neighbors all smaller than 0.5.

For a, the expected output mask would be

array([[False, False, False, False],
       [False, False , False, True],
       [False, False, False, True],
       [False, False, True, False],
       [False, True, True, True]])

CodePudding user response:

You can use a 2D convolution:

from scipy.signal import convolve2d

kernel = np.array([[1, 1,  1],
                   [1, 10, 1],
                   [1, 1,  1]])

out = convolve2d(a>0.5, kernel, mode='same') > 10

The kernel is designed to count 10 for each center > 0.5 and 1 for each surrounding value > 0.5, and the convolution computes the sum. Thus if you have a total sum > 10, you know that the value is > 0.5 and so it at least one of its neighbors.

Output:

array([[False, False, False, False],
       [False, False, False,  True],
       [False, False, False,  True],
       [False, False,  True, False],
       [False,  True,  True,  True]])

more classical alternative

from scipy.signal import convolve2d

m = a>0.5

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

out = m & (convolve2d(m, kernel, mode='same') > 0)
  • Related