NumPy:填充数组中{1}周围的字段

时间:2016-10-24 16:22:52

标签: python arrays numpy matrix

假设我有一个4x4矩阵,如下所示:

[[0, 0, 0, 0]
 [0, 0, 1, 0]
 [0, 0, 0, 0]
 [0, 0, 0, 0]]

我想写一个函数,它接受一个的所有4个周围的字段,并将它们变成1。

以上矩阵将成为:

[[0, 0, 1, 0]
 [0, 1, 1, 1]
 [0, 0, 1, 0]
 [0, 0, 0, 0]]

我知道使用if语句可以做到这一点,但我真的想优化我的代码。

矩阵只包含0&1和1。如果1位于矩阵的边缘,则1不应该环绕,即如果最左边的字段是1,则最右边的字段仍然保持为0.此外,我使用的是Python 3.5

是否有更多数学或简洁的方法来做到这一点?

2 个答案:

答案 0 :(得分:6)

这看起来像二元扩张。 SciPy中有一个可以有效实现这一功能的功能:

>>> from scipy.ndimage import binary_dilation
>>> x
array([[0, 0, 0, 0],
       [0, 0, 1, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]])

>>> binary_dilation(x).astype(int)
array([[0, 0, 1, 0],
       [0, 1, 1, 1],
       [0, 0, 1, 0],
       [0, 0, 0, 0]])

边缘处的1s处理,因为您已指定它们应该是(即没有包装)。

有关更多选项和参数,请参阅documentation

答案 1 :(得分:1)

FWIW,这是一种只使用Numpy的方法。我们用行和数据填充原始数据。零列,然后将填充数组的按位或OR偏移副本放在一起。

import numpy as np

def fill(data):
    rows, cols = data.shape
    padded = np.pad(data, 1, 'constant', constant_values=0)
    result = np.copy(data)
    for r, c in ((0, 1), (1, 0), (1, 2), (2, 1)):
        result |= padded[r:r+rows, c:c+cols]
    return result

data = np.asarray(
    [
        [0, 0, 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0],
    ], dtype='uint8')
print(data, '\n')

result = fill(data)
print(result)

<强>输出

[[0 0 0 0]
 [0 0 1 0]
 [0 0 0 0]
 [0 0 0 0]] 

[[0 0 1 0]
 [0 1 1 1]
 [0 0 1 0]
 [0 0 0 0]]