【问题标题】:Pad a numpy array with random values within a given range?用给定范围内的随机值填充一个numpy数组?
【发布时间】:2018-12-25 12:12:29
【问题描述】:

我希望能够用一组随机值为数组(实际上是一个图像文件)设置边界。 numpy.pad() 函数没有任何模式可以执行此操作。有没有一种速记方法来实现这一点,还是我必须从头开始创建一个函数?

【问题讨论】:

标签: python numpy random padding


【解决方案1】:

我认为您需要自己创建一个填充函数以传递给np.pad。 这个用随机整数填充。

def random_pad(vec, pad_width, *_, **__):
    vec[:pad_width[0]] = np.random.randint(20, 30, size=pad_width[0])
    vec[vec.size-pad_width[1]:] = np.random.randint(30,40, size=pad_width[1])

您可以像这样将它与 np.pad 一起使用:

In [13]: img = np.arange(12).reshape(3, 4)

In [14]: img
Out[14]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

In [15]: np.pad(img, ((2,3), (1,4)), mode=random_pad)
Out[15]: 
array([[26, 21, 22, 24, 21, 37, 37, 37, 39],
       [26, 25, 23, 29, 20, 39, 38, 30, 31],
       [26,  0,  1,  2,  3, 37, 31, 32, 36],
       [29,  4,  5,  6,  7, 30, 32, 33, 37],
       [24,  8,  9, 10, 11, 33, 34, 33, 37],
       [26, 36, 36, 36, 30, 32, 36, 38, 31],
       [29, 33, 34, 38, 35, 31, 33, 37, 33],
       [23, 37, 33, 33, 34, 32, 37, 33, 35]])

【讨论】:

    【解决方案2】:

    这可能不是最节省空间的,但一种方法是创建一个新数组并将现有数组放置在该数组的中心。

    >>> import numpy as np
    >>> np.random.seed(444)
    >>> arr = np.zeros((4, 5))  # your image array
    >>> newsize = tuple(i + 2 for i in arr.shape)
    >>> new = np.random.randint(low=0, high=50, size=newsize)
    >>> new[1:-1, 1:-1] = arr
    >>> new
    array([[ 3, 48, 23,  8,  3, 39, 12],
           [47,  0,  0,  0,  0,  0, 15],
           [34,  0,  0,  0,  0,  0,  0],
           [ 6,  0,  0,  0,  0,  0,  6],
           [39,  0,  0,  0,  0,  0, 13],
           [ 2, 15,  9, 34,  9, 24, 25]])
    

    这是假设您的图像是灰度 (2d) 而不是 3 维 MxNx4 RGBA 数组。在这种情况下,您需要new[1:-1, 1:-1, 1:-1]

    您也可以通过将可调用对象传递给np.pad() 来执行此操作,但有一个警告(见下文):

    from functools import partial
    
    def _pad_random(vector, pad_width, iaxis, kwargs, low, high):
        a, b = np.random.randint(low, high, size=2)
        vector[:pad_width[0]] = a
        vector[-pad_width[1]:] = b
        return vector
    
    pad_random = partial(_pad_random, low=0, high=50)
    

    用法:

    >>> np.pad(arr, 1, pad_random)
    array([[23., 19.,  6., 47., 17.,  7., 26.],
           [26.,  0.,  0.,  0.,  0.,  0., 37.],
           [39.,  0.,  0.,  0.,  0.,  0., 39.],
           [39.,  0.,  0.,  0.,  0.,  0., 42.],
           [28.,  0.,  0.,  0.,  0.,  0., 47.],
           [11., 32., 37.,  2., 38., 30., 44.]])
    

    警告:看起来,当您将函数传递给np.pad()mode 参数时,该函数会被多次调用。这是一个直接来自文档的示例,其中包含一些打印调用:

    >>> def pad_with(vector, pad_width, iaxis, kwargs):
    ...     pad_value = kwargs.get('padder', 10)
    ...     print(vector[:pad_width[0]])
    ...     print(vector[-pad_width[1]:])
    ...     vector[:pad_width[0]] = pad_value
    ...     vector[-pad_width[1]:] = pad_value
    ...     return vector
    ...
    >>> arr = np.arange(6).reshape(3, 2)
    
    >>> np.pad(arr, 1, pad_with)
    [0]
    [0]
    [0]
    [0]
    [0]
    [0]
    [0]
    [0]
    [10]
    [10]
    [0]
    [0]
    [0]
    [0]
    [0]
    [0]
    [10]
    [10]
    array([[10, 10, 10, 10],
           [10,  0,  1, 10],
           [10,  2,  3, 10],
           [10,  4,  5, 10],
           [10, 10, 10, 10]])
    

    因此,只要图像不太大,使用上述第一种方法可能会更省时。

    【讨论】:

      猜你喜欢
      • 2021-06-20
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-16
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多